LCOV - code coverage report
Current view: top level - vcl/source/gdi - outdev2.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 468 953 49.1 %
Date: 2012-08-25 Functions: 23 37 62.2 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 557 1854 30.0 %

           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                 :            : #include <tools/debug.hxx>
      30                 :            : 
      31                 :            : #include <vcl/bitmap.hxx>
      32                 :            : #include <vcl/bitmapex.hxx>
      33                 :            : #include <vcl/window.hxx>
      34                 :            : #include <vcl/metaact.hxx>
      35                 :            : #include <vcl/gdimtf.hxx>
      36                 :            : #include <vcl/virdev.hxx>
      37                 :            : #include <vcl/bmpacc.hxx>
      38                 :            : #include <vcl/outdev.hxx>
      39                 :            : #include <vcl/window.hxx>
      40                 :            : #include <vcl/image.hxx>
      41                 :            : 
      42                 :            : #include <bmpfast.hxx>
      43                 :            : #include <salbmp.hxx>
      44                 :            : #include <salgdi.hxx>
      45                 :            : #include <impbmp.hxx>
      46                 :            : #include <sallayout.hxx>
      47                 :            : #include <image.h>
      48                 :            : #include <outdev.h>
      49                 :            : #include <window.h>
      50                 :            : #include <region.h>
      51                 :            : #include <outdata.hxx>
      52                 :            : 
      53                 :            : DBG_NAMEEX( OutputDevice )
      54                 :            : 
      55                 :            : // =======================================================================
      56                 :            : 
      57                 :            : // -----------
      58                 :            : // - Defines -
      59                 :            : // -----------
      60                 :            : 
      61                 :            : #define OUTDEV_INIT()                       \
      62                 :            : {                                           \
      63                 :            :     if ( !IsDeviceOutputNecessary() )       \
      64                 :            :         return;                             \
      65                 :            :                                             \
      66                 :            :     if ( !mpGraphics )                      \
      67                 :            :         if ( !ImplGetGraphics() )           \
      68                 :            :             return;                         \
      69                 :            :                                             \
      70                 :            :     if ( mbInitClipRegion )                 \
      71                 :            :         ImplInitClipRegion();               \
      72                 :            :                                             \
      73                 :            :     if ( mbOutputClipped )                  \
      74                 :            :         return;                             \
      75                 :            : }
      76                 :            : 
      77                 :            : // -------------
      78                 :            : // - externals -
      79                 :            : // -------------
      80                 :            : 
      81                 :            : extern const sal_uLong nVCLRLut[ 6 ];
      82                 :            : extern const sal_uLong nVCLGLut[ 6 ];
      83                 :            : extern const sal_uLong nVCLBLut[ 6 ];
      84                 :            : extern const sal_uLong nVCLDitherLut[ 256 ];
      85                 :            : extern const sal_uLong nVCLLut[ 256 ];
      86                 :            : 
      87                 :            : // =======================================================================
      88                 :            : 
      89                 :     223038 : sal_uLong ImplAdjustTwoRect( SalTwoRect& rTwoRect, const Size& rSizePix )
      90                 :            : {
      91                 :     223038 :     sal_uLong nMirrFlags = 0;
      92                 :            : 
      93         [ -  + ]:     223038 :     if ( rTwoRect.mnDestWidth < 0 )
      94                 :            :     {
      95                 :          0 :         rTwoRect.mnSrcX = rSizePix.Width() - rTwoRect.mnSrcX - rTwoRect.mnSrcWidth;
      96                 :          0 :         rTwoRect.mnDestWidth = -rTwoRect.mnDestWidth;
      97                 :          0 :         rTwoRect.mnDestX -= rTwoRect.mnDestWidth-1;
      98                 :          0 :         nMirrFlags |= BMP_MIRROR_HORZ;
      99                 :            :     }
     100                 :            : 
     101         [ -  + ]:     223038 :     if ( rTwoRect.mnDestHeight < 0 )
     102                 :            :     {
     103                 :          0 :         rTwoRect.mnSrcY = rSizePix.Height() - rTwoRect.mnSrcY - rTwoRect.mnSrcHeight;
     104                 :          0 :         rTwoRect.mnDestHeight = -rTwoRect.mnDestHeight;
     105                 :          0 :         rTwoRect.mnDestY -= rTwoRect.mnDestHeight-1;
     106                 :          0 :         nMirrFlags |= BMP_MIRROR_VERT;
     107                 :            :     }
     108                 :            : 
     109 [ +  - ][ +  - ]:     892152 :     if( ( rTwoRect.mnSrcX < 0 ) || ( rTwoRect.mnSrcX >= rSizePix.Width() ) ||
           [ +  -  +  -  
             +  -  -  + ]
                 [ -  + ]
     110                 :     223038 :         ( rTwoRect.mnSrcY < 0 ) || ( rTwoRect.mnSrcY >= rSizePix.Height() ) ||
     111                 :     223038 :         ( ( rTwoRect.mnSrcX + rTwoRect.mnSrcWidth ) > rSizePix.Width() ) ||
     112                 :     223038 :         ( ( rTwoRect.mnSrcY + rTwoRect.mnSrcHeight ) > rSizePix.Height() ) )
     113                 :            :     {
     114                 :            :         const Rectangle aSourceRect( Point( rTwoRect.mnSrcX, rTwoRect.mnSrcY ),
     115         [ #  # ]:          0 :                                      Size( rTwoRect.mnSrcWidth, rTwoRect.mnSrcHeight ) );
     116                 :          0 :         Rectangle       aCropRect( aSourceRect );
     117                 :            : 
     118 [ #  # ][ #  # ]:          0 :         aCropRect.Intersection( Rectangle( Point(), rSizePix ) );
     119                 :            : 
     120 [ #  # ][ #  # ]:          0 :         if( aCropRect.IsEmpty() )
     121                 :          0 :             rTwoRect.mnSrcWidth = rTwoRect.mnSrcHeight = rTwoRect.mnDestWidth = rTwoRect.mnDestHeight = 0;
     122                 :            :         else
     123                 :            :         {
     124         [ #  # ]:          0 :             const double    fFactorX = ( rTwoRect.mnSrcWidth > 1 ) ? (double) ( rTwoRect.mnDestWidth - 1 ) / ( rTwoRect.mnSrcWidth - 1 ) : 0.0;
     125         [ #  # ]:          0 :             const double    fFactorY = ( rTwoRect.mnSrcHeight > 1 ) ? (double) ( rTwoRect.mnDestHeight - 1 ) / ( rTwoRect.mnSrcHeight - 1 ) : 0.0;
     126                 :            : 
     127                 :          0 :             const long nDstX1 = rTwoRect.mnDestX + FRound( fFactorX * ( aCropRect.Left() - rTwoRect.mnSrcX ) );
     128                 :          0 :             const long nDstY1 = rTwoRect.mnDestY + FRound( fFactorY * ( aCropRect.Top() - rTwoRect.mnSrcY ) );
     129                 :          0 :             const long nDstX2 = rTwoRect.mnDestX + FRound( fFactorX * ( aCropRect.Right() - rTwoRect.mnSrcX ) );
     130                 :          0 :             const long nDstY2 = rTwoRect.mnDestY + FRound( fFactorY * ( aCropRect.Bottom() - rTwoRect.mnSrcY ) );
     131                 :            : 
     132                 :          0 :             rTwoRect.mnSrcX = aCropRect.Left();
     133                 :          0 :             rTwoRect.mnSrcY = aCropRect.Top();
     134         [ #  # ]:          0 :             rTwoRect.mnSrcWidth = aCropRect.GetWidth();
     135         [ #  # ]:          0 :             rTwoRect.mnSrcHeight = aCropRect.GetHeight();
     136                 :          0 :             rTwoRect.mnDestX = nDstX1;
     137                 :          0 :             rTwoRect.mnDestY = nDstY1;
     138                 :          0 :             rTwoRect.mnDestWidth = nDstX2 - nDstX1 + 1;
     139                 :          0 :             rTwoRect.mnDestHeight = nDstY2 - nDstY1 + 1;
     140                 :            :         }
     141                 :            :     }
     142                 :            : 
     143                 :     223038 :     return nMirrFlags;
     144                 :            : }
     145                 :            : 
     146                 :            : // =======================================================================
     147                 :            : 
     148                 :      50596 : void ImplAdjustTwoRect( SalTwoRect& rTwoRect, const Rectangle& rValidSrcRect )
     149                 :            : {
     150 [ +  + ][ +  +  :     221710 :     if( ( rTwoRect.mnSrcX < rValidSrcRect.Left() ) || ( rTwoRect.mnSrcX >= rValidSrcRect.Right() ) ||
          +  -  +  +  +  
                +  +  + ]
                 [ +  + ]
     151                 :     100582 :         ( rTwoRect.mnSrcY < rValidSrcRect.Top() ) || ( rTwoRect.mnSrcY >= rValidSrcRect.Bottom() ) ||
     152                 :      50272 :         ( ( rTwoRect.mnSrcX + rTwoRect.mnSrcWidth ) > rValidSrcRect.Right() ) ||
     153                 :      20260 :         ( ( rTwoRect.mnSrcY + rTwoRect.mnSrcHeight ) > rValidSrcRect.Bottom() ) )
     154                 :            :     {
     155                 :            :         const Rectangle aSourceRect( Point( rTwoRect.mnSrcX, rTwoRect.mnSrcY ),
     156         [ +  - ]:      39196 :                                      Size( rTwoRect.mnSrcWidth, rTwoRect.mnSrcHeight ) );
     157                 :      39196 :         Rectangle       aCropRect( aSourceRect );
     158                 :            : 
     159         [ +  - ]:      39196 :         aCropRect.Intersection( rValidSrcRect );
     160                 :            : 
     161 [ +  - ][ +  + ]:      39196 :         if( aCropRect.IsEmpty() )
     162                 :         44 :             rTwoRect.mnSrcWidth = rTwoRect.mnSrcHeight = rTwoRect.mnDestWidth = rTwoRect.mnDestHeight = 0;
     163                 :            :         else
     164                 :            :         {
     165         [ +  + ]:      39152 :             const double    fFactorX = ( rTwoRect.mnSrcWidth > 1 ) ? (double) ( rTwoRect.mnDestWidth - 1 ) / ( rTwoRect.mnSrcWidth - 1 ) : 0.0;
     166         [ +  + ]:      39152 :             const double    fFactorY = ( rTwoRect.mnSrcHeight > 1 ) ? (double) ( rTwoRect.mnDestHeight - 1 ) / ( rTwoRect.mnSrcHeight - 1 ) : 0.0;
     167                 :            : 
     168                 :      39152 :             const long nDstX1 = rTwoRect.mnDestX + FRound( fFactorX * ( aCropRect.Left() - rTwoRect.mnSrcX ) );
     169                 :      39152 :             const long nDstY1 = rTwoRect.mnDestY + FRound( fFactorY * ( aCropRect.Top() - rTwoRect.mnSrcY ) );
     170                 :      39152 :             const long nDstX2 = rTwoRect.mnDestX + FRound( fFactorX * ( aCropRect.Right() - rTwoRect.mnSrcX ) );
     171                 :      39152 :             const long nDstY2 = rTwoRect.mnDestY + FRound( fFactorY * ( aCropRect.Bottom() - rTwoRect.mnSrcY ) );
     172                 :            : 
     173                 :      39152 :             rTwoRect.mnSrcX = aCropRect.Left();
     174                 :      39152 :             rTwoRect.mnSrcY = aCropRect.Top();
     175         [ +  - ]:      39152 :             rTwoRect.mnSrcWidth = aCropRect.GetWidth();
     176         [ +  - ]:      39152 :             rTwoRect.mnSrcHeight = aCropRect.GetHeight();
     177                 :      39152 :             rTwoRect.mnDestX = nDstX1;
     178                 :      39152 :             rTwoRect.mnDestY = nDstY1;
     179                 :      39152 :             rTwoRect.mnDestWidth = nDstX2 - nDstX1 + 1;
     180                 :      39196 :             rTwoRect.mnDestHeight = nDstY2 - nDstY1 + 1;
     181                 :            :         }
     182                 :            :     }
     183                 :      50596 : }
     184                 :            : 
     185                 :            : // =======================================================================
     186                 :            : 
     187                 :      50171 : void OutputDevice::ImplDrawOutDevDirect( const OutputDevice* pSrcDev, void* pVoidPosAry )
     188                 :            : {
     189                 :      50171 :     SalTwoRect*            pPosAry = (SalTwoRect*)pVoidPosAry;
     190                 :            :     SalGraphics*        pGraphics2;
     191                 :            : 
     192         [ -  + ]:      50171 :     if ( this == pSrcDev )
     193                 :          0 :         pGraphics2 = NULL;
     194                 :            :     else
     195                 :            :     {
     196   [ +  +  +  - ]:      70320 :         if ( (GetOutDevType() != pSrcDev->GetOutDevType()) ||
                 [ +  - ]
     197                 :      20149 :              (GetOutDevType() != OUTDEV_WINDOW) )
     198                 :            :         {
     199         [ -  + ]:      50171 :             if ( !pSrcDev->mpGraphics )
     200                 :            :             {
     201 [ #  # ][ #  # ]:          0 :                 if ( !((OutputDevice*)pSrcDev)->ImplGetGraphics() )
     202                 :            :                     return;
     203                 :            :             }
     204                 :      50171 :             pGraphics2 = pSrcDev->mpGraphics;
     205                 :            :         }
     206                 :            :         else
     207                 :            :         {
     208         [ #  # ]:          0 :             if ( ((Window*)this)->mpWindowImpl->mpFrameWindow == ((Window*)pSrcDev)->mpWindowImpl->mpFrameWindow )
     209                 :          0 :                 pGraphics2 = NULL;
     210                 :            :             else
     211                 :            :             {
     212         [ #  # ]:          0 :                 if ( !pSrcDev->mpGraphics )
     213                 :            :                 {
     214 [ #  # ][ #  # ]:          0 :                     if ( !((OutputDevice*)pSrcDev)->ImplGetGraphics() )
     215                 :            :                         return;
     216                 :            :                 }
     217                 :          0 :                 pGraphics2 = pSrcDev->mpGraphics;
     218                 :            : 
     219         [ #  # ]:          0 :                 if ( !mpGraphics )
     220                 :            :                 {
     221 [ #  # ][ #  # ]:          0 :                     if ( !ImplGetGraphics() )
     222                 :            :                         return;
     223                 :            :                 }
     224                 :            :                 DBG_ASSERT( mpGraphics && pSrcDev->mpGraphics,
     225                 :            :                             "OutputDevice::DrawOutDev(): We need more than one Graphics" );
     226                 :            :             }
     227                 :            :         }
     228                 :            :     }
     229                 :            : 
     230                 :            :     // #102532# Offset only has to be pseudo window offset
     231                 :            :     const Rectangle aSrcOutRect( Point( pSrcDev->mnOutOffX, pSrcDev->mnOutOffY ),
     232         [ +  - ]:      50171 :                                  Size( pSrcDev->mnOutWidth, pSrcDev->mnOutHeight ) );
     233                 :            : 
     234         [ +  - ]:      50171 :     ImplAdjustTwoRect( *pPosAry, aSrcOutRect );
     235                 :            : 
     236 [ +  + ][ +  - ]:      50171 :     if ( pPosAry->mnSrcWidth && pPosAry->mnSrcHeight && pPosAry->mnDestWidth && pPosAry->mnDestHeight )
         [ +  - ][ +  - ]
     237                 :            :     {
     238                 :            :         // --- RTL --- if this is no window, but pSrcDev is a window
     239                 :            :         // mirroring may be required
     240                 :            :         // because only windows have a SalGraphicsLayout
     241                 :            :         // mirroring is performed here
     242 [ +  + ][ +  - ]:      50127 :         if( (GetOutDevType() != OUTDEV_WINDOW) && pGraphics2 && (pGraphics2->GetLayout() & SAL_LAYOUT_BIDI_RTL) )
         [ -  + ][ -  + ]
     243                 :            :         {
     244                 :          0 :             SalTwoRect pPosAry2 = *pPosAry;
     245         [ #  # ]:          0 :             pGraphics2->mirror( pPosAry2.mnSrcX, pPosAry2.mnSrcWidth, pSrcDev );
     246         [ #  # ]:          0 :             mpGraphics->CopyBits( &pPosAry2, pGraphics2, this, pSrcDev );
     247                 :            :         }
     248                 :            :         else
     249         [ +  - ]:      50171 :             mpGraphics->CopyBits( pPosAry, pGraphics2, this, pSrcDev );
     250                 :            :     }
     251                 :            : }
     252                 :            : 
     253                 :        425 : void OutputDevice::DrawOutDev( const Point& rDestPt, const Size& rDestSize,
     254                 :            :                                const Point& rSrcPt,  const Size& rSrcSize )
     255                 :            : {
     256                 :            :     OSL_TRACE( "OutputDevice::DrawOutDev()" );
     257                 :            :     DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
     258                 :            :     DBG_ASSERT( meOutDevType != OUTDEV_PRINTER, "Don't use OutputDevice::DrawOutDev(...) with printer devices!" );
     259                 :            : 
     260 [ +  - ][ +  - ]:        425 :     if( ImplIsRecordLayout() )
     261                 :            :         return;
     262                 :            : 
     263         [ +  - ]:        425 :     if ( meOutDevType == OUTDEV_PRINTER )
     264                 :            :         return;
     265                 :            : 
     266         [ -  + ]:        425 :     if ( ROP_INVERT == meRasterOp )
     267                 :            :     {
     268 [ #  # ][ #  # ]:          0 :         DrawRect( Rectangle( rDestPt, rDestSize ) );
     269                 :            :         return;
     270                 :            :     }
     271                 :            : 
     272         [ -  + ]:        425 :     if ( mpMetaFile )
     273                 :            :     {
     274         [ #  # ]:          0 :         const Bitmap aBmp( GetBitmap( rSrcPt, rSrcSize ) );
     275 [ #  # ][ #  # ]:          0 :         mpMetaFile->AddAction( new MetaBmpScaleAction( rDestPt, rDestSize, aBmp ) );
         [ #  # ][ #  # ]
     276                 :            :     }
     277                 :            : 
     278 [ +  - ][ +  + ]:        425 :     OUTDEV_INIT();
         [ +  - ][ +  - ]
         [ +  + ][ +  - ]
                 [ +  - ]
     279                 :            : 
     280                 :            :     SalTwoRect aPosAry;
     281         [ +  - ]:        425 :     aPosAry.mnSrcWidth   = ImplLogicWidthToDevicePixel( rSrcSize.Width() );
     282         [ +  - ]:        425 :     aPosAry.mnSrcHeight  = ImplLogicHeightToDevicePixel( rSrcSize.Height() );
     283         [ +  - ]:        425 :     aPosAry.mnDestWidth  = ImplLogicWidthToDevicePixel( rDestSize.Width() );
     284         [ +  - ]:        425 :     aPosAry.mnDestHeight = ImplLogicHeightToDevicePixel( rDestSize.Height() );
     285                 :            : 
     286 [ +  - ][ +  - ]:        425 :     if ( aPosAry.mnSrcWidth && aPosAry.mnSrcHeight && aPosAry.mnDestWidth && aPosAry.mnDestHeight )
         [ +  - ][ +  - ]
     287                 :            :     {
     288         [ +  - ]:        425 :         aPosAry.mnSrcX       = ImplLogicXToDevicePixel( rSrcPt.X() );
     289         [ +  - ]:        425 :         aPosAry.mnSrcY       = ImplLogicYToDevicePixel( rSrcPt.Y() );
     290         [ +  - ]:        425 :         aPosAry.mnDestX      = ImplLogicXToDevicePixel( rDestPt.X() );
     291         [ +  - ]:        425 :         aPosAry.mnDestY      = ImplLogicYToDevicePixel( rDestPt.Y() );
     292                 :            : 
     293                 :            :         const Rectangle aSrcOutRect( Point( mnOutOffX, mnOutOffY ),
     294         [ +  - ]:        425 :                                      Size( mnOutWidth, mnOutHeight ) );
     295                 :            : 
     296         [ +  - ]:        425 :         ImplAdjustTwoRect( aPosAry, aSrcOutRect );
     297                 :            : 
     298 [ +  - ][ +  - ]:        425 :         if ( aPosAry.mnSrcWidth && aPosAry.mnSrcHeight && aPosAry.mnDestWidth && aPosAry.mnDestHeight )
         [ +  - ][ +  - ]
     299         [ +  - ]:        425 :             mpGraphics->CopyBits( &aPosAry, NULL, this, NULL );
     300                 :            :     }
     301                 :            : 
     302         [ -  + ]:        425 :     if( mpAlphaVDev )
     303         [ #  # ]:        425 :         mpAlphaVDev->DrawOutDev( rDestPt, rDestSize, rSrcPt, rSrcSize );
     304                 :            : }
     305                 :            : 
     306                 :      50402 : void OutputDevice::DrawOutDev( const Point& rDestPt, const Size& rDestSize,
     307                 :            :                                const Point& rSrcPt,  const Size& rSrcSize,
     308                 :            :                                const OutputDevice& rOutDev )
     309                 :            : {
     310                 :            :     OSL_TRACE( "OutputDevice::DrawOutDev()" );
     311                 :            :     DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
     312                 :            :     DBG_CHKOBJ( &rOutDev, OutputDevice, ImplDbgCheckOutputDevice );
     313                 :            :     DBG_ASSERT( meOutDevType != OUTDEV_PRINTER, "Don't use OutputDevice::DrawOutDev(...) with printer devices!" );
     314                 :            :     DBG_ASSERT( rOutDev.meOutDevType != OUTDEV_PRINTER, "Don't use OutputDevice::DrawOutDev(...) with printer devices!" );
     315                 :            : 
     316 [ +  - ][ +  - ]:      50402 :     if ( (meOutDevType == OUTDEV_PRINTER) || (rOutDev.meOutDevType == OUTDEV_PRINTER) || ImplIsRecordLayout() )
         [ +  - ][ -  + ]
                 [ +  - ]
     317                 :            :         return;
     318                 :            : 
     319         [ -  + ]:      50402 :     if ( ROP_INVERT == meRasterOp )
     320                 :            :     {
     321 [ #  # ][ #  # ]:          0 :         DrawRect( Rectangle( rDestPt, rDestSize ) );
     322                 :            :         return;
     323                 :            :     }
     324                 :            : 
     325         [ -  + ]:      50402 :     if ( mpMetaFile )
     326                 :            :     {
     327         [ #  # ]:          0 :         const Bitmap aBmp( rOutDev.GetBitmap( rSrcPt, rSrcSize ) );
     328 [ #  # ][ #  # ]:          0 :         mpMetaFile->AddAction( new MetaBmpScaleAction( rDestPt, rDestSize, aBmp ) );
         [ #  # ][ #  # ]
     329                 :            :     }
     330                 :            : 
     331 [ +  + ][ +  + ]:      50402 :     OUTDEV_INIT();
         [ +  - ][ +  - ]
         [ +  + ][ +  - ]
                 [ +  - ]
     332                 :            : 
     333                 :            :     SalTwoRect aPosAry;
     334         [ +  - ]:      50171 :     aPosAry.mnSrcX       = rOutDev.ImplLogicXToDevicePixel( rSrcPt.X() );
     335         [ +  - ]:      50171 :     aPosAry.mnSrcY       = rOutDev.ImplLogicYToDevicePixel( rSrcPt.Y() );
     336         [ +  - ]:      50171 :     aPosAry.mnSrcWidth   = rOutDev.ImplLogicWidthToDevicePixel( rSrcSize.Width() );
     337         [ +  - ]:      50171 :     aPosAry.mnSrcHeight  = rOutDev.ImplLogicHeightToDevicePixel( rSrcSize.Height() );
     338         [ +  - ]:      50171 :     aPosAry.mnDestX      = ImplLogicXToDevicePixel( rDestPt.X() );
     339         [ +  - ]:      50171 :     aPosAry.mnDestY      = ImplLogicYToDevicePixel( rDestPt.Y() );
     340         [ +  - ]:      50171 :     aPosAry.mnDestWidth  = ImplLogicWidthToDevicePixel( rDestSize.Width() );
     341         [ +  - ]:      50171 :     aPosAry.mnDestHeight = ImplLogicHeightToDevicePixel( rDestSize.Height() );
     342                 :            : 
     343         [ -  + ]:      50171 :     if( mpAlphaVDev )
     344                 :            :     {
     345         [ #  # ]:          0 :         if( rOutDev.mpAlphaVDev )
     346                 :            :         {
     347                 :            :             // alpha-blend source over destination
     348 [ #  # ][ #  # ]:          0 :             DrawBitmapEx( rDestPt, rDestSize, rOutDev.GetBitmapEx(rSrcPt, rSrcSize) );
                 [ #  # ]
     349                 :            : 
     350                 :            :             // This would be mode SOURCE:
     351                 :            :             // copy source alpha channel to our alpha channel
     352                 :            :             //mpAlphaVDev->DrawOutDev( rDestPt, rDestSize, rSrcPt, rSrcSize, *rOutDev.mpAlphaVDev );
     353                 :            :         }
     354                 :            :         else
     355                 :            :         {
     356         [ #  # ]:          0 :             ImplDrawOutDevDirect( &rOutDev, &aPosAry );
     357                 :            : 
     358                 :            :             // #i32109#: make destination rectangle opaque - source has no alpha
     359 [ #  # ][ #  # ]:          0 :             mpAlphaVDev->ImplFillOpaqueRectangle( Rectangle(rDestPt, rDestSize) );
     360                 :            :         }
     361                 :            :     }
     362                 :            :     else
     363                 :            :     {
     364         [ -  + ]:      50171 :         if( rOutDev.mpAlphaVDev )
     365                 :            :         {
     366                 :            :             // alpha-blend source over destination
     367 [ #  # ][ #  # ]:          0 :             DrawBitmapEx( rDestPt, rDestSize, rOutDev.GetBitmapEx(rSrcPt, rSrcSize) );
                 [ #  # ]
     368                 :            :         }
     369                 :            :         else
     370                 :            :         {
     371                 :            :             // no alpha at all, neither in source nor destination device
     372         [ +  - ]:      50402 :             ImplDrawOutDevDirect( &rOutDev, &aPosAry );
     373                 :            :         }
     374                 :            :     }
     375                 :            : }
     376                 :            : 
     377                 :          0 : void OutputDevice::CopyArea( const Point& rDestPt,
     378                 :            :                              const Point& rSrcPt,  const Size& rSrcSize,
     379                 :            :                              sal_uInt16 nFlags )
     380                 :            : {
     381                 :            :     OSL_TRACE( "OutputDevice::CopyArea()" );
     382                 :            :     DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
     383                 :            :     DBG_ASSERT( meOutDevType != OUTDEV_PRINTER, "Don't use OutputDevice::CopyArea(...) with printer devices!" );
     384                 :            : 
     385 [ #  # ][ #  # ]:          0 :     if ( meOutDevType == OUTDEV_PRINTER || ImplIsRecordLayout() )
         [ #  # ][ #  # ]
     386                 :            :         return;
     387                 :            : 
     388                 :          0 :     RasterOp eOldRop = GetRasterOp();
     389         [ #  # ]:          0 :     SetRasterOp( ROP_OVERPAINT );
     390                 :            : 
     391 [ #  # ][ #  # ]:          0 :     OUTDEV_INIT();
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     392                 :            : 
     393                 :            :     SalTwoRect aPosAry;
     394         [ #  # ]:          0 :     aPosAry.mnSrcWidth   = ImplLogicWidthToDevicePixel( rSrcSize.Width() );
     395         [ #  # ]:          0 :     aPosAry.mnSrcHeight  = ImplLogicHeightToDevicePixel( rSrcSize.Height() );
     396                 :            : 
     397 [ #  # ][ #  # ]:          0 :     if ( aPosAry.mnSrcWidth && aPosAry.mnSrcHeight )
     398                 :            :     {
     399         [ #  # ]:          0 :         aPosAry.mnSrcX       = ImplLogicXToDevicePixel( rSrcPt.X() );
     400         [ #  # ]:          0 :         aPosAry.mnSrcY       = ImplLogicYToDevicePixel( rSrcPt.Y() );
     401         [ #  # ]:          0 :         aPosAry.mnDestX      = ImplLogicXToDevicePixel( rDestPt.X() );
     402         [ #  # ]:          0 :         aPosAry.mnDestY      = ImplLogicYToDevicePixel( rDestPt.Y() );
     403                 :          0 :         aPosAry.mnDestWidth  = aPosAry.mnSrcWidth;
     404                 :          0 :         aPosAry.mnDestHeight = aPosAry.mnSrcHeight;
     405                 :            : 
     406                 :            :         const Rectangle aSrcOutRect( Point( mnOutOffX, mnOutOffY ),
     407         [ #  # ]:          0 :                                      Size( mnOutWidth, mnOutHeight ) );
     408                 :            :         const Rectangle aSrcRect( Point( aPosAry.mnSrcX, aPosAry.mnSrcY ),
     409         [ #  # ]:          0 :                                   Size( aPosAry.mnSrcWidth, aPosAry.mnSrcHeight ) );
     410                 :            : 
     411         [ #  # ]:          0 :         ImplAdjustTwoRect( aPosAry, aSrcOutRect );
     412                 :            : 
     413 [ #  # ][ #  # ]:          0 :         if ( aPosAry.mnSrcWidth && aPosAry.mnSrcHeight && aPosAry.mnDestWidth && aPosAry.mnDestHeight )
         [ #  # ][ #  # ]
     414                 :            :         {
     415 [ #  # ][ #  # ]:          0 :             if ( (meOutDevType == OUTDEV_WINDOW) && (nFlags & COPYAREA_WINDOWINVALIDATE) )
     416                 :            :             {
     417                 :            :                 ((Window*)this)->ImplMoveAllInvalidateRegions( aSrcRect,
     418                 :            :                                                                aPosAry.mnDestX-aPosAry.mnSrcX,
     419                 :            :                                                                aPosAry.mnDestY-aPosAry.mnSrcY,
     420         [ #  # ]:          0 :                                                                false );
     421                 :            : 
     422                 :            :                 mpGraphics->CopyArea( aPosAry.mnDestX, aPosAry.mnDestY,
     423                 :            :                                       aPosAry.mnSrcX, aPosAry.mnSrcY,
     424                 :            :                                       aPosAry.mnSrcWidth, aPosAry.mnSrcHeight,
     425         [ #  # ]:          0 :                                       SAL_COPYAREA_WINDOWINVALIDATE, this );
     426                 :            :             }
     427                 :            :             else
     428                 :            :             {
     429                 :          0 :                 aPosAry.mnDestWidth  = aPosAry.mnSrcWidth;
     430                 :          0 :                 aPosAry.mnDestHeight = aPosAry.mnSrcHeight;
     431         [ #  # ]:          0 :                 mpGraphics->CopyBits( &aPosAry, NULL, this, NULL );
     432                 :            :             }
     433                 :            :         }
     434                 :            :     }
     435                 :            : 
     436         [ #  # ]:          0 :     SetRasterOp( eOldRop );
     437                 :            : 
     438         [ #  # ]:          0 :     if( mpAlphaVDev )
     439         [ #  # ]:          0 :         mpAlphaVDev->CopyArea( rDestPt, rSrcPt, rSrcSize, nFlags );
     440                 :            : }
     441                 :            : 
     442                 :          0 : void OutputDevice::ImplDrawFrameDev( const Point& rPt, const Point& rDevPt, const Size& rDevSize,
     443                 :            :                                      const OutputDevice& rOutDev, const Region& rRegion )
     444                 :            : {
     445                 :            :     DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
     446                 :            : 
     447                 :          0 :     GDIMetaFile*    pOldMetaFile = mpMetaFile;
     448                 :          0 :     bool            bOldMap = mbMap;
     449                 :          0 :     RasterOp        eOldROP = GetRasterOp();
     450                 :          0 :     mpMetaFile = NULL;
     451                 :          0 :     mbMap = false;
     452         [ #  # ]:          0 :     SetRasterOp( ROP_OVERPAINT );
     453                 :            : 
     454         [ #  # ]:          0 :     if ( !IsDeviceOutputNecessary() )
     455                 :            :         return;
     456                 :            : 
     457         [ #  # ]:          0 :     if ( !mpGraphics )
     458                 :            :     {
     459 [ #  # ][ #  # ]:          0 :         if ( !ImplGetGraphics() )
     460                 :            :             return;
     461                 :            :     }
     462                 :            : 
     463                 :            :     // ClipRegion zuruecksetzen
     464 [ #  # ][ #  # ]:          0 :     if ( rRegion.IsNull() )
     465         [ #  # ]:          0 :         mpGraphics->ResetClipRegion();
     466                 :            :     else
     467         [ #  # ]:          0 :         ImplSelectClipRegion( rRegion );
     468                 :            : 
     469                 :            :     SalTwoRect aPosAry;
     470                 :          0 :     aPosAry.mnSrcX       = rDevPt.X();
     471                 :          0 :     aPosAry.mnSrcY       = rDevPt.Y();
     472                 :          0 :     aPosAry.mnSrcWidth   = rDevSize.Width();
     473                 :          0 :     aPosAry.mnSrcHeight  = rDevSize.Height();
     474                 :          0 :     aPosAry.mnDestX      = rPt.X();
     475                 :          0 :     aPosAry.mnDestY      = rPt.Y();
     476                 :          0 :     aPosAry.mnDestWidth  = rDevSize.Width();
     477                 :          0 :     aPosAry.mnDestHeight = rDevSize.Height();
     478         [ #  # ]:          0 :     ImplDrawOutDevDirect( &rOutDev, &aPosAry );
     479                 :            : 
     480                 :            :     // Ensure that ClipRegion is recalculated and set
     481                 :          0 :     mbInitClipRegion = true;
     482                 :            : 
     483         [ #  # ]:          0 :     SetRasterOp( eOldROP );
     484                 :          0 :     mbMap = bOldMap;
     485                 :          0 :     mpMetaFile = pOldMetaFile;
     486                 :            : }
     487                 :            : 
     488                 :          0 : void OutputDevice::ImplGetFrameDev( const Point& rPt, const Point& rDevPt, const Size& rDevSize,
     489                 :            :                                     OutputDevice& rDev )
     490                 :            : {
     491                 :            :     DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
     492                 :            : 
     493                 :          0 :     bool bOldMap = mbMap;
     494                 :          0 :     mbMap = false;
     495                 :          0 :     rDev.DrawOutDev( rDevPt, rDevSize, rPt, rDevSize, *this );
     496                 :          0 :     mbMap = bOldMap;
     497                 :          0 : }
     498                 :            : 
     499                 :     221820 : void OutputDevice::DrawBitmap( const Point& rDestPt, const Bitmap& rBitmap )
     500                 :            : {
     501                 :            :     OSL_TRACE( "OutputDevice::DrawBitmap()" );
     502                 :            : 
     503 [ +  - ][ +  - ]:     221820 :     if( ImplIsRecordLayout() )
     504                 :     221820 :         return;
     505                 :            : 
     506         [ +  - ]:     221820 :     const Size aSizePix( rBitmap.GetSizePixel() );
     507 [ +  - ][ +  - ]:     221820 :     ImplDrawBitmap( rDestPt, PixelToLogic( aSizePix ), Point(), aSizePix, rBitmap, META_BMP_ACTION );
     508                 :            : 
     509         [ -  + ]:     221820 :     if( mpAlphaVDev )
     510                 :            :     {
     511                 :            :         // #i32109#: Make bitmap area opaque
     512 [ #  # ][ #  # ]:     221820 :         mpAlphaVDev->ImplFillOpaqueRectangle( Rectangle(rDestPt, PixelToLogic( aSizePix )) );
                 [ #  # ]
     513                 :            :     }
     514                 :            : }
     515                 :            : 
     516                 :         26 : void OutputDevice::DrawBitmap( const Point& rDestPt, const Size& rDestSize, const Bitmap& rBitmap )
     517                 :            : {
     518                 :            :     OSL_TRACE( "OutputDevice::DrawBitmap( Size )" );
     519                 :            : 
     520         [ -  + ]:         26 :     if( ImplIsRecordLayout() )
     521                 :         26 :         return;
     522                 :            : 
     523         [ +  - ]:         26 :     ImplDrawBitmap( rDestPt, rDestSize, Point(), rBitmap.GetSizePixel(), rBitmap, META_BMPSCALE_ACTION );
     524                 :            : 
     525         [ -  + ]:         26 :     if( mpAlphaVDev )
     526                 :            :     {
     527                 :            :         // #i32109#: Make bitmap area opaque
     528         [ #  # ]:          0 :         mpAlphaVDev->ImplFillOpaqueRectangle( Rectangle(rDestPt, rDestSize) );
     529                 :            :     }
     530                 :            : }
     531                 :            : 
     532                 :          0 : void OutputDevice::DrawBitmap( const Point& rDestPt, const Size& rDestSize,
     533                 :            :                                const Point& rSrcPtPixel, const Size& rSrcSizePixel,
     534                 :            :                                const Bitmap& rBitmap )
     535                 :            : {
     536                 :            :     OSL_TRACE( "OutputDevice::DrawBitmap( Point, Size )" );
     537                 :            : 
     538         [ #  # ]:          0 :     if( ImplIsRecordLayout() )
     539                 :          0 :         return;
     540                 :            : 
     541                 :          0 :     ImplDrawBitmap( rDestPt, rDestSize, rSrcPtPixel, rSrcSizePixel, rBitmap, META_BMPSCALEPART_ACTION );
     542                 :            : 
     543         [ #  # ]:          0 :     if( mpAlphaVDev )
     544                 :            :     {
     545                 :            :         // #i32109#: Make bitmap area opaque
     546         [ #  # ]:          0 :         mpAlphaVDev->ImplFillOpaqueRectangle( Rectangle(rDestPt, rDestSize) );
     547                 :            :     }
     548                 :            : }
     549                 :            : 
     550                 :     221846 : void OutputDevice::ImplDrawBitmap( const Point& rDestPt, const Size& rDestSize,
     551                 :            :                                    const Point& rSrcPtPixel, const Size& rSrcSizePixel,
     552                 :            :                                    const Bitmap& rBitmap, const sal_uLong nAction )
     553                 :            : {
     554                 :            :     DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
     555                 :            : 
     556         [ +  - ]:     221846 :     Bitmap aBmp( rBitmap );
     557                 :            : 
     558         [ -  + ]:     221846 :     if ( ( mnDrawMode & DRAWMODE_NOBITMAP ) )
     559                 :            :     {
     560                 :            :         return;
     561                 :            :     }
     562         [ -  + ]:     221846 :     else if ( ROP_INVERT == meRasterOp )
     563                 :            :     {
     564 [ #  # ][ #  # ]:          0 :         DrawRect( Rectangle( rDestPt, rDestSize ) );
     565                 :            :         return;
     566                 :            :     }
     567         [ -  + ]:     221846 :     else if ( mnDrawMode & ( DRAWMODE_BLACKBITMAP | DRAWMODE_WHITEBITMAP |
     568                 :            :                              DRAWMODE_GRAYBITMAP  | DRAWMODE_GHOSTEDBITMAP ) )
     569                 :            :     {
     570         [ #  # ]:          0 :         if ( mnDrawMode & ( DRAWMODE_BLACKBITMAP | DRAWMODE_WHITEBITMAP ) )
     571                 :            :         {
     572                 :            :             sal_uInt8 cCmpVal;
     573                 :            : 
     574         [ #  # ]:          0 :             if ( mnDrawMode & DRAWMODE_BLACKBITMAP )
     575         [ #  # ]:          0 :                 cCmpVal = ( mnDrawMode & DRAWMODE_GHOSTEDBITMAP ) ? 0x80 : 0;
     576                 :            :             else
     577                 :          0 :                 cCmpVal = 255;
     578                 :            : 
     579                 :          0 :             Color aCol( cCmpVal, cCmpVal, cCmpVal );
     580         [ #  # ]:          0 :             Push( PUSH_LINECOLOR | PUSH_FILLCOLOR );
     581         [ #  # ]:          0 :             SetLineColor( aCol );
     582         [ #  # ]:          0 :             SetFillColor( aCol );
     583 [ #  # ][ #  # ]:          0 :             DrawRect( Rectangle( rDestPt, rDestSize ) );
     584         [ #  # ]:          0 :             Pop();
     585                 :            :             return;
     586                 :            :         }
     587         [ #  # ]:          0 :         else if( !!aBmp )
     588                 :            :         {
     589         [ #  # ]:          0 :             if ( mnDrawMode & DRAWMODE_GRAYBITMAP )
     590         [ #  # ]:          0 :                 aBmp.Convert( BMP_CONVERSION_8BIT_GREYS );
     591                 :            : 
     592         [ #  # ]:          0 :             if ( mnDrawMode & DRAWMODE_GHOSTEDBITMAP )
     593         [ #  # ]:          0 :                 aBmp.Convert( BMP_CONVERSION_GHOSTED );
     594                 :            :         }
     595                 :            :     }
     596                 :            : 
     597         [ +  + ]:     221846 :     if ( mpMetaFile )
     598                 :            :     {
     599   [ -  +  -  - ]:         15 :         switch( nAction )
     600                 :            :         {
     601                 :            :             case( META_BMP_ACTION ):
     602 [ #  # ][ #  # ]:          0 :                 mpMetaFile->AddAction( new MetaBmpAction( rDestPt, aBmp ) );
                 [ #  # ]
     603                 :          0 :             break;
     604                 :            : 
     605                 :            :             case( META_BMPSCALE_ACTION ):
     606 [ +  - ][ +  - ]:         15 :                 mpMetaFile->AddAction( new MetaBmpScaleAction( rDestPt, rDestSize, aBmp ) );
                 [ +  - ]
     607                 :         15 :             break;
     608                 :            : 
     609                 :            :             case( META_BMPSCALEPART_ACTION ):
     610                 :            :                 mpMetaFile->AddAction( new MetaBmpScalePartAction(
     611 [ #  # ][ #  # ]:          0 :                     rDestPt, rDestSize, rSrcPtPixel, rSrcSizePixel, aBmp ) );
                 [ #  # ]
     612                 :         15 :             break;
     613                 :            :         }
     614                 :            :     }
     615                 :            : 
     616 [ +  + ][ -  + ]:     221846 :     OUTDEV_INIT();
         [ #  # ][ #  # ]
         [ +  + ][ +  - ]
                 [ -  + ]
     617                 :            : 
     618         [ +  + ]:     221728 :     if( !aBmp.IsEmpty() )
     619                 :            :     {
     620                 :            :         SalTwoRect aPosAry;
     621                 :            : 
     622                 :     219953 :         aPosAry.mnSrcX = rSrcPtPixel.X();
     623                 :     219953 :         aPosAry.mnSrcY = rSrcPtPixel.Y();
     624                 :     219953 :         aPosAry.mnSrcWidth = rSrcSizePixel.Width();
     625                 :     219953 :         aPosAry.mnSrcHeight = rSrcSizePixel.Height();
     626         [ +  - ]:     219953 :         aPosAry.mnDestX = ImplLogicXToDevicePixel( rDestPt.X() );
     627         [ +  - ]:     219953 :         aPosAry.mnDestY = ImplLogicYToDevicePixel( rDestPt.Y() );
     628         [ +  - ]:     219953 :         aPosAry.mnDestWidth = ImplLogicWidthToDevicePixel( rDestSize.Width() );
     629         [ +  - ]:     219953 :         aPosAry.mnDestHeight = ImplLogicHeightToDevicePixel( rDestSize.Height() );
     630                 :            : 
     631 [ +  - ][ +  - ]:     219953 :         if ( aPosAry.mnSrcWidth && aPosAry.mnSrcHeight && aPosAry.mnDestWidth && aPosAry.mnDestHeight )
         [ +  - ][ +  - ]
     632                 :            :         {
     633 [ +  - ][ +  - ]:     219953 :             const sal_uLong nMirrFlags = ImplAdjustTwoRect( aPosAry, aBmp.GetSizePixel() );
     634                 :            : 
     635         [ -  + ]:     219953 :             if ( nMirrFlags )
     636         [ #  # ]:          0 :                 aBmp.Mirror( nMirrFlags );
     637                 :            : 
     638                 :            :             /* #i75264# (corrected with #i81576#)
     639                 :            :             * sometimes a bitmap is scaled to a ridiculous size and drawn
     640                 :            :             * to a quite normal VDev, so only a very small part of
     641                 :            :             * the scaled bitmap will be visible. However actually scaling
     642                 :            :             * the bitmap will use so much memory that we end with a crash.
     643                 :            :             * Workaround: since only a small part of the scaled bitmap will
     644                 :            :             * be actually drawn anyway (because of clipping on the device
     645                 :            :             * boundary), limit the destination and source rectangles so
     646                 :            :             * that the destination rectangle will overlap the device but only
     647                 :            :             * be reasonably (say factor 2) larger than the device itself.
     648                 :            :             */
     649 [ +  - ][ -  + ]:     219953 :             if( aPosAry.mnDestWidth > 2048 || aPosAry.mnDestHeight > 2048 )
     650                 :            :             {
     651 [ #  # ][ #  # ]:          0 :                  if( meOutDevType == OUTDEV_WINDOW ||
                 [ #  # ]
     652                 :            :                      (meOutDevType == OUTDEV_VIRDEV && mpPDFWriter == 0 ) )
     653                 :            :                 {
     654                 :            :                     // #i81576# do the following trick only if there is overlap at all
     655                 :            :                     // else the formulae don't work
     656                 :            :                     // theoretically in this case we wouldn't need to draw the bitmap at all
     657                 :            :                     // however there are some esoteric case where that is needed
     658 [ #  # ][ #  # ]:          0 :                     if( aPosAry.mnDestX + aPosAry.mnDestWidth >= 0
         [ #  # ][ #  # ]
     659                 :            :                         && aPosAry.mnDestX < mnOutWidth
     660                 :            :                         && aPosAry.mnDestY + aPosAry.mnDestHeight >= 0
     661                 :            :                         && aPosAry.mnDestY < mnOutHeight )
     662                 :            :                     {
     663                 :            :                         // reduce scaling to something reasonable taking into account the output size
     664 [ #  # ][ #  # ]:          0 :                         if( aPosAry.mnDestWidth > 3*mnOutWidth && aPosAry.mnSrcWidth )
     665                 :            :                         {
     666                 :          0 :                             const double nScaleX = aPosAry.mnDestWidth/double(aPosAry.mnSrcWidth);
     667                 :            : 
     668         [ #  # ]:          0 :                             if( aPosAry.mnDestX + aPosAry.mnDestWidth > mnOutWidth )
     669                 :            :                             {
     670                 :          0 :                                 aPosAry.mnDestWidth = Max(long(0),mnOutWidth-aPosAry.mnDestX);
     671                 :            :                             }
     672         [ #  # ]:          0 :                             if( aPosAry.mnDestX < 0 )
     673                 :            :                             {
     674                 :          0 :                                 aPosAry.mnDestWidth += aPosAry.mnDestX;
     675                 :          0 :                                 aPosAry.mnSrcX -= sal::static_int_cast<long>(aPosAry.mnDestX / nScaleX);
     676                 :          0 :                                 aPosAry.mnDestX = 0;
     677                 :            :                             }
     678                 :            : 
     679                 :          0 :                             aPosAry.mnSrcWidth = sal::static_int_cast<long>(aPosAry.mnDestWidth / nScaleX);
     680                 :            :                         }
     681                 :            : 
     682 [ #  # ][ #  # ]:          0 :                         if( aPosAry.mnDestHeight > 3*mnOutHeight && aPosAry.mnSrcHeight != 0 )
     683                 :            :                         {
     684                 :          0 :                             const double nScaleY = aPosAry.mnDestHeight/double(aPosAry.mnSrcHeight);
     685                 :            : 
     686         [ #  # ]:          0 :                             if( aPosAry.mnDestY + aPosAry.mnDestHeight > mnOutHeight )
     687                 :            :                             {
     688                 :          0 :                                 aPosAry.mnDestHeight = Max(long(0),mnOutHeight-aPosAry.mnDestY);
     689                 :            :                             }
     690         [ #  # ]:          0 :                             if( aPosAry.mnDestY < 0 )
     691                 :            :                             {
     692                 :          0 :                                 aPosAry.mnDestHeight += aPosAry.mnDestY;
     693                 :          0 :                                 aPosAry.mnSrcY -= sal::static_int_cast<long>(aPosAry.mnDestY / nScaleY);
     694                 :          0 :                                 aPosAry.mnDestY = 0;
     695                 :            :                             }
     696                 :            : 
     697                 :          0 :                             aPosAry.mnSrcHeight = sal::static_int_cast<long>(aPosAry.mnDestHeight / nScaleY);
     698                 :            :                         }
     699                 :            :                     }
     700                 :            :                 }
     701                 :            :             }
     702                 :            : 
     703 [ +  - ][ +  - ]:     219953 :             if ( aPosAry.mnSrcWidth && aPosAry.mnSrcHeight && aPosAry.mnDestWidth && aPosAry.mnDestHeight )
         [ +  - ][ +  - ]
     704                 :            :             {
     705                 :     219953 :                 const double nScaleX = aPosAry.mnDestWidth  / static_cast<double>( aPosAry.mnSrcWidth );
     706                 :     219953 :                 const double nScaleY = aPosAry.mnDestHeight / static_cast<double>( aPosAry.mnSrcHeight );
     707                 :            :                 // If subsampling, use Bitmap::Scale for subsampling for better quality.
     708 [ +  - ][ +  + ]:     219953 :                 if ( meOutDevType != OUTDEV_PRINTER &&
         [ +  + ][ -  + ]
     709                 :            :                     nAction == META_BMPSCALE_ACTION &&
     710                 :            :                     (nScaleX < 1.0 || nScaleY < 1.0) )
     711                 :            :                 {
     712         [ +  - ]:          7 :                     aBmp.Scale ( nScaleX, nScaleY );
     713                 :          7 :                     aPosAry.mnSrcWidth = aPosAry.mnDestWidth;
     714                 :          7 :                     aPosAry.mnSrcHeight = aPosAry.mnDestHeight;
     715                 :            :                 }
     716 [ +  - ][ +  - ]:     221728 :                 mpGraphics->DrawBitmap( &aPosAry, *aBmp.ImplGetImpBitmap()->ImplGetSalBitmap(), this );
     717                 :            :             }
     718                 :            :         }
     719 [ +  - ][ +  + ]:     221846 :     }
     720                 :            : }
     721                 :            : 
     722                 :     149475 : void OutputDevice::DrawBitmapEx( const Point& rDestPt,
     723                 :            :                                  const BitmapEx& rBitmapEx )
     724                 :            : {
     725                 :            :     OSL_TRACE( "OutputDevice::DrawBitmapEx()" );
     726                 :            : 
     727         [ -  + ]:     149475 :     if( ImplIsRecordLayout() )
     728                 :     149475 :         return;
     729                 :            : 
     730         [ +  + ]:     149475 :     if( TRANSPARENT_NONE == rBitmapEx.GetTransparentType() )
     731         [ +  - ]:      39022 :         DrawBitmap( rDestPt, rBitmapEx.GetBitmap() );
     732                 :            :     else
     733                 :            :     {
     734                 :     110453 :         const Size aSizePix( rBitmapEx.GetSizePixel() );
     735 [ +  - ][ +  - ]:     110453 :         ImplDrawBitmapEx( rDestPt, PixelToLogic( aSizePix ), Point(), aSizePix, rBitmapEx, META_BMPEX_ACTION );
     736                 :            :     }
     737                 :            : }
     738                 :            : 
     739                 :      21541 : void OutputDevice::DrawBitmapEx( const Point& rDestPt, const Size& rDestSize,
     740                 :            :                                  const BitmapEx& rBitmapEx )
     741                 :            : {
     742                 :            :     OSL_TRACE( "OutputDevice::DrawBitmapEx( Size )" );
     743                 :            : 
     744         [ -  + ]:      21541 :     if( ImplIsRecordLayout() )
     745                 :      21541 :         return;
     746                 :            : 
     747         [ +  + ]:      21541 :     if ( TRANSPARENT_NONE == rBitmapEx.GetTransparentType() )
     748         [ +  - ]:         13 :         DrawBitmap( rDestPt, rDestSize, rBitmapEx.GetBitmap() );
     749                 :            :     else
     750         [ +  - ]:      21528 :         ImplDrawBitmapEx( rDestPt, rDestSize, Point(), rBitmapEx.GetSizePixel(), rBitmapEx, META_BMPEXSCALE_ACTION );
     751                 :            : }
     752                 :            : 
     753                 :     119769 : void OutputDevice::DrawBitmapEx( const Point& rDestPt, const Size& rDestSize,
     754                 :            :                                  const Point& rSrcPtPixel, const Size& rSrcSizePixel,
     755                 :            :                                  const BitmapEx& rBitmapEx )
     756                 :            : {
     757                 :            :     OSL_TRACE( "OutputDevice::DrawBitmapEx( Point, Size )" );
     758                 :            : 
     759         [ -  + ]:     119769 :     if( ImplIsRecordLayout() )
     760                 :     119769 :         return;
     761                 :            : 
     762         [ -  + ]:     119769 :     if( TRANSPARENT_NONE == rBitmapEx.GetTransparentType() )
     763         [ #  # ]:          0 :         DrawBitmap( rDestPt, rDestSize, rSrcPtPixel, rSrcSizePixel, rBitmapEx.GetBitmap() );
     764                 :            :     else
     765                 :     119769 :         ImplDrawBitmapEx( rDestPt, rDestSize, rSrcPtPixel, rSrcSizePixel, rBitmapEx, META_BMPEXSCALEPART_ACTION );
     766                 :            : }
     767                 :            : 
     768                 :     251750 : void OutputDevice::ImplDrawBitmapEx( const Point& rDestPt, const Size& rDestSize,
     769                 :            :                                      const Point& rSrcPtPixel, const Size& rSrcSizePixel,
     770                 :            :                                      const BitmapEx& rBitmapEx, const sal_uLong nAction )
     771                 :            : {
     772                 :            :     DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
     773                 :            : 
     774         [ +  - ]:     251750 :     BitmapEx aBmpEx( rBitmapEx );
     775                 :            : 
     776         [ -  + ]:     251750 :     if ( mnDrawMode & DRAWMODE_NOBITMAP )
     777                 :            :         return;
     778         [ -  + ]:     251750 :     else if ( ROP_INVERT == meRasterOp )
     779                 :            :     {
     780 [ #  # ][ #  # ]:          0 :         DrawRect( Rectangle( rDestPt, rDestSize ) );
     781                 :            :         return;
     782                 :            :     }
     783         [ -  + ]:     251750 :     else if ( mnDrawMode & ( DRAWMODE_BLACKBITMAP | DRAWMODE_WHITEBITMAP |
     784                 :            :                              DRAWMODE_GRAYBITMAP | DRAWMODE_GHOSTEDBITMAP ) )
     785                 :            :     {
     786         [ #  # ]:          0 :         if ( mnDrawMode & ( DRAWMODE_BLACKBITMAP | DRAWMODE_WHITEBITMAP ) )
     787                 :            :         {
     788 [ #  # ][ #  # ]:          0 :             Bitmap  aColorBmp( aBmpEx.GetSizePixel(), ( mnDrawMode & DRAWMODE_GHOSTEDBITMAP ) ? 4 : 1 );
     789                 :            :             sal_uInt8   cCmpVal;
     790                 :            : 
     791         [ #  # ]:          0 :             if ( mnDrawMode & DRAWMODE_BLACKBITMAP )
     792         [ #  # ]:          0 :                 cCmpVal = ( mnDrawMode & DRAWMODE_GHOSTEDBITMAP ) ? 0x80 : 0;
     793                 :            :             else
     794                 :          0 :                 cCmpVal = 255;
     795                 :            : 
     796         [ #  # ]:          0 :             aColorBmp.Erase( Color( cCmpVal, cCmpVal, cCmpVal ) );
     797                 :            : 
     798 [ #  # ][ #  # ]:          0 :             if( aBmpEx.IsAlpha() )
     799                 :            :             {
     800                 :            :                 // Create one-bit mask out of alpha channel, by
     801                 :            :                 // thresholding it at alpha=0.5. As
     802                 :            :                 // DRAWMODE_BLACK/WHITEBITMAP requires monochrome
     803                 :            :                 // output, having alpha-induced grey levels is not
     804                 :            :                 // acceptable.
     805 [ #  # ][ #  # ]:          0 :                 Bitmap aMask( aBmpEx.GetAlpha().GetBitmap() );
                 [ #  # ]
     806         [ #  # ]:          0 :                 aMask.MakeMono( 129 );
     807 [ #  # ][ #  # ]:          0 :                 aBmpEx = BitmapEx( aColorBmp, aMask );
         [ #  # ][ #  # ]
     808                 :            :             }
     809                 :            :             else
     810                 :            :             {
     811 [ #  # ][ #  # ]:          0 :                 aBmpEx = BitmapEx( aColorBmp, aBmpEx.GetMask() );
         [ #  # ][ #  # ]
                 [ #  # ]
     812         [ #  # ]:          0 :             }
     813                 :            :         }
     814         [ #  # ]:          0 :         else if( !!aBmpEx )
     815                 :            :         {
     816         [ #  # ]:          0 :             if ( mnDrawMode & DRAWMODE_GRAYBITMAP )
     817         [ #  # ]:          0 :                 aBmpEx.Convert( BMP_CONVERSION_8BIT_GREYS );
     818                 :            : 
     819         [ #  # ]:          0 :             if ( mnDrawMode & DRAWMODE_GHOSTEDBITMAP )
     820         [ #  # ]:          0 :                 aBmpEx.Convert( BMP_CONVERSION_GHOSTED );
     821                 :            :         }
     822                 :            :     }
     823                 :            : 
     824         [ +  + ]:     251750 :     if ( mpMetaFile )
     825                 :            :     {
     826   [ +  +  +  - ]:        583 :         switch( nAction )
     827                 :            :         {
     828                 :            :             case( META_BMPEX_ACTION ):
     829 [ +  - ][ +  - ]:          6 :                 mpMetaFile->AddAction( new MetaBmpExAction( rDestPt, aBmpEx ) );
                 [ +  - ]
     830                 :          6 :             break;
     831                 :            : 
     832                 :            :             case( META_BMPEXSCALE_ACTION ):
     833 [ +  - ][ +  - ]:         16 :                 mpMetaFile->AddAction( new MetaBmpExScaleAction( rDestPt, rDestSize, aBmpEx ) );
                 [ +  - ]
     834                 :         16 :             break;
     835                 :            : 
     836                 :            :             case( META_BMPEXSCALEPART_ACTION ):
     837                 :            :                 mpMetaFile->AddAction( new MetaBmpExScalePartAction( rDestPt, rDestSize,
     838 [ +  - ][ +  - ]:        561 :                                                                      rSrcPtPixel, rSrcSizePixel, aBmpEx ) );
                 [ +  - ]
     839                 :        583 :             break;
     840                 :            :         }
     841                 :            :     }
     842                 :            : 
     843 [ +  + ][ +  + ]:     251750 :     OUTDEV_INIT();
         [ +  - ][ -  + ]
         [ +  + ][ +  - ]
                 [ +  + ]
     844                 :            : 
     845         [ -  + ]:     251167 :     if( OUTDEV_PRINTER == meOutDevType )
     846                 :            :     {
     847 [ #  # ][ #  # ]:          0 :         if( aBmpEx.IsAlpha() )
     848                 :            :         {
     849                 :            :             // #107169# For true alpha bitmaps, no longer masking the
     850                 :            :             // bitmap, but perform a full alpha blend against a white
     851                 :            :             // background here.
     852         [ #  # ]:          0 :             Bitmap aBmp( aBmpEx.GetBitmap() );
     853 [ #  # ][ #  # ]:          0 :             aBmp.Blend( aBmpEx.GetAlpha(), Color( COL_WHITE) );
                 [ #  # ]
     854 [ #  # ][ #  # ]:          0 :             DrawBitmap( rDestPt, rDestSize, rSrcPtPixel, rSrcSizePixel, aBmp );
     855                 :            :         }
     856                 :            :         else
     857                 :            :         {
     858 [ #  # ][ #  # ]:          0 :             Bitmap aBmp( aBmpEx.GetBitmap() ), aMask( aBmpEx.GetMask() );
     859         [ #  # ]:          0 :             aBmp.Replace( aMask, Color( COL_WHITE ) );
     860 [ #  # ][ #  # ]:          0 :             ImplPrintTransparent( aBmp, aMask, rDestPt, rDestSize, rSrcPtPixel, rSrcSizePixel );
                 [ #  # ]
     861                 :            :         }
     862                 :            :         return;
     863                 :            :     }
     864 [ +  - ][ +  + ]:     251167 :     else if( aBmpEx.IsAlpha() )
     865                 :            :     {
     866 [ +  - ][ +  - ]:     248082 :         ImplDrawAlpha( aBmpEx.GetBitmap(), aBmpEx.GetAlpha(), rDestPt, rDestSize, rSrcPtPixel, rSrcSizePixel );
         [ +  - ][ +  - ]
                 [ +  - ]
     867                 :            :         return;
     868                 :            :     }
     869                 :            : 
     870         [ +  - ]:       3085 :     if( !( !aBmpEx ) )
     871                 :            :     {
     872                 :            :         SalTwoRect aPosAry;
     873                 :            : 
     874                 :       3085 :         aPosAry.mnSrcX = rSrcPtPixel.X();
     875                 :       3085 :         aPosAry.mnSrcY = rSrcPtPixel.Y();
     876                 :       3085 :         aPosAry.mnSrcWidth = rSrcSizePixel.Width();
     877                 :       3085 :         aPosAry.mnSrcHeight = rSrcSizePixel.Height();
     878         [ +  - ]:       3085 :         aPosAry.mnDestX = ImplLogicXToDevicePixel( rDestPt.X() );
     879         [ +  - ]:       3085 :         aPosAry.mnDestY = ImplLogicYToDevicePixel( rDestPt.Y() );
     880         [ +  - ]:       3085 :         aPosAry.mnDestWidth = ImplLogicWidthToDevicePixel( rDestSize.Width() );
     881         [ +  - ]:       3085 :         aPosAry.mnDestHeight = ImplLogicHeightToDevicePixel( rDestSize.Height() );
     882                 :            : 
     883         [ +  - ]:       3085 :         const sal_uLong nMirrFlags = ImplAdjustTwoRect( aPosAry, aBmpEx.GetSizePixel() );
     884                 :            : 
     885 [ +  - ][ +  - ]:       3085 :         if( aPosAry.mnSrcWidth && aPosAry.mnSrcHeight && aPosAry.mnDestWidth && aPosAry.mnDestHeight )
         [ +  - ][ +  - ]
     886                 :            :         {
     887                 :            : 
     888         [ -  + ]:       3085 :             if( nMirrFlags )
     889         [ #  # ]:          0 :                 aBmpEx.Mirror( nMirrFlags );
     890                 :            : 
     891         [ +  - ]:       3085 :             const ImpBitmap* pImpBmp = aBmpEx.ImplGetBitmapImpBitmap();
     892         [ +  - ]:       3085 :             const ImpBitmap* pMaskBmp = aBmpEx.ImplGetMaskImpBitmap();
     893                 :            : 
     894         [ +  - ]:       3085 :             if ( pMaskBmp )
     895                 :            :             {
     896                 :            :                 // #4919452# reduce operation area to bounds of
     897                 :            :                 // cliprect. since masked transparency involves
     898                 :            :                 // creation of a large vdev and copying the screen
     899                 :            :                 // content into that (slooow read from framebuffer),
     900                 :            :                 // that should considerably increase performance for
     901                 :            :                 // large bitmaps and small clippings.
     902                 :            : 
     903                 :            :                 // Note that this optimisation is a workaround for a
     904                 :            :                 // Writer peculiarity, namely, to decompose background
     905                 :            :                 // graphics into myriads of disjunct, tiny
     906                 :            :                 // rectangles. That otherwise kills us here, since for
     907                 :            :                 // transparent output, SAL always prepares the whole
     908                 :            :                 // bitmap, if aPosAry contains the whole bitmap (and
     909                 :            :                 // it's _not_ to blame for that).
     910                 :            : 
     911                 :            :                 // Note the call to ImplPixelToDevicePixel(), since
     912                 :            :                 // aPosAry already contains the mnOutOff-offsets, they
     913                 :            :                 // also have to be applied to the region
     914 [ +  - ][ +  - ]:       3085 :                 Rectangle aClipRegionBounds( ImplPixelToDevicePixel(maRegion).GetBoundRect() );
                 [ +  - ]
     915                 :            : 
     916                 :            :                 // TODO: Also respect scaling (that's a bit tricky,
     917                 :            :                 // since the source points have to move fractional
     918                 :            :                 // amounts (which is not possible, thus has to be
     919                 :            :                 // emulated by increases copy area)
     920                 :            :                 // const double nScaleX( aPosAry.mnDestWidth / aPosAry.mnSrcWidth );
     921                 :            :                 // const double nScaleY( aPosAry.mnDestHeight / aPosAry.mnSrcHeight );
     922                 :            : 
     923                 :            :                 // for now, only identity scales allowed
     924 [ +  - ][ +  + ]:       3085 :                 if( !aClipRegionBounds.IsEmpty() &&
         [ +  - ][ +  - ]
                 [ +  + ]
     925                 :            :                     aPosAry.mnDestWidth == aPosAry.mnSrcWidth &&
     926                 :            :                     aPosAry.mnDestHeight == aPosAry.mnSrcHeight )
     927                 :            :                 {
     928                 :            :                     // now intersect dest rect with clip region
     929                 :            :                     aClipRegionBounds.Intersection( Rectangle( aPosAry.mnDestX,
     930                 :            :                                                                aPosAry.mnDestY,
     931                 :            :                                                                aPosAry.mnDestX + aPosAry.mnDestWidth - 1,
     932 [ +  - ][ +  - ]:       2136 :                                                                aPosAry.mnDestY + aPosAry.mnDestHeight - 1 ) );
     933                 :            : 
     934                 :            :                     // Note: I could theoretically optimize away the
     935                 :            :                     // DrawBitmap below, if the region is empty
     936                 :            :                     // here. Unfortunately, cannot rule out that
     937                 :            :                     // somebody relies on the side effects.
     938 [ +  - ][ +  - ]:       2136 :                     if( !aClipRegionBounds.IsEmpty() )
     939                 :            :                     {
     940                 :       2136 :                         aPosAry.mnSrcX += aClipRegionBounds.Left() - aPosAry.mnDestX;
     941                 :       2136 :                         aPosAry.mnSrcY += aClipRegionBounds.Top() - aPosAry.mnDestY;
     942         [ +  - ]:       2136 :                         aPosAry.mnSrcWidth = aClipRegionBounds.GetWidth();
     943         [ +  - ]:       2136 :                         aPosAry.mnSrcHeight = aClipRegionBounds.GetHeight();
     944                 :            : 
     945                 :       2136 :                         aPosAry.mnDestX = aClipRegionBounds.Left();
     946                 :       2136 :                         aPosAry.mnDestY = aClipRegionBounds.Top();
     947         [ +  - ]:       2136 :                         aPosAry.mnDestWidth = aClipRegionBounds.GetWidth();
     948         [ +  - ]:       2136 :                         aPosAry.mnDestHeight = aClipRegionBounds.GetHeight();
     949                 :            :                     }
     950                 :            :                 }
     951                 :            : 
     952                 :       3085 :                 mpGraphics->DrawBitmap( &aPosAry, *pImpBmp->ImplGetSalBitmap(),
     953                 :       3085 :                                         *pMaskBmp->ImplGetSalBitmap(),
     954         [ +  - ]:       3085 :                                         this );
     955                 :            : 
     956                 :            :                 // #110958# Paint mask to alpha channel. Luckily, the
     957                 :            :                 // black and white representation of the mask maps to
     958                 :            :                 // the alpha channel
     959                 :            : 
     960                 :            :                 // #i25167# Restrict mask painting to _opaque_ areas
     961                 :            :                 // of the mask, otherwise we spoil areas where no
     962                 :            :                 // bitmap content was ever visible. Interestingly
     963                 :            :                 // enough, this can be achieved by taking the mask as
     964                 :            :                 // the transparency mask of itself
     965         [ +  + ]:       3085 :                 if( mpAlphaVDev )
     966                 :            :                     mpAlphaVDev->DrawBitmapEx( rDestPt,
     967                 :            :                                                rDestSize,
     968                 :            :                                                BitmapEx( aBmpEx.GetMask(),
     969 [ +  - ][ +  - ]:       3085 :                                                          aBmpEx.GetMask() ) );
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
                 [ +  - ]
     970                 :            :             }
     971                 :            :             else
     972                 :            :             {
     973         [ #  # ]:          0 :                 mpGraphics->DrawBitmap( &aPosAry, *pImpBmp->ImplGetSalBitmap(), this );
     974                 :            : 
     975         [ #  # ]:          0 :                 if( mpAlphaVDev )
     976                 :            :                 {
     977                 :            :                     // #i32109#: Make bitmap area opaque
     978 [ #  # ][ #  # ]:       3085 :                     mpAlphaVDev->ImplFillOpaqueRectangle( Rectangle(rDestPt, rDestSize) );
     979                 :            :                 }
     980                 :            :             }
     981                 :            :         }
     982 [ +  - ][ +  + ]:     251750 :     }
     983                 :            : }
     984                 :            : 
     985                 :          0 : void OutputDevice::DrawMask( const Point& rDestPt,
     986                 :            :                              const Bitmap& rBitmap, const Color& rMaskColor )
     987                 :            : {
     988                 :            :     OSL_TRACE( "OutputDevice::DrawMask()" );
     989                 :            : 
     990 [ #  # ][ #  # ]:          0 :     if( ImplIsRecordLayout() )
     991                 :          0 :         return;
     992                 :            : 
     993         [ #  # ]:          0 :     const Size aSizePix( rBitmap.GetSizePixel() );
     994 [ #  # ][ #  # ]:          0 :     ImplDrawMask( rDestPt, PixelToLogic( aSizePix ), Point(), aSizePix, rBitmap, rMaskColor, META_MASK_ACTION );
     995                 :            : 
     996         [ #  # ]:          0 :     if( mpAlphaVDev )
     997                 :            :     {
     998         [ #  # ]:          0 :         const Bitmap& rMask( rBitmap.CreateMask( rMaskColor ) );
     999                 :            : 
    1000                 :            :         // #i25167# Restrict mask painting to _opaque_ areas
    1001                 :            :         // of the mask, otherwise we spoil areas where no
    1002                 :            :         // bitmap content was ever visible. Interestingly
    1003                 :            :         // enough, this can be achieved by taking the mask as
    1004                 :            :         // the transparency mask of itself
    1005                 :            :         mpAlphaVDev->DrawBitmapEx( rDestPt,
    1006                 :            :                                    PixelToLogic( aSizePix ),
    1007 [ #  # ][ #  # ]:          0 :                                    BitmapEx( rMask, rMask ) );
         [ #  # ][ #  # ]
                 [ #  # ]
    1008                 :            :     }
    1009                 :            : }
    1010                 :            : 
    1011                 :          0 : void OutputDevice::DrawMask( const Point& rDestPt, const Size& rDestSize,
    1012                 :            :                              const Bitmap& rBitmap, const Color& rMaskColor )
    1013                 :            : {
    1014                 :            :     OSL_TRACE( "OutputDevice::DrawMask( Size )" );
    1015                 :            : 
    1016         [ #  # ]:          0 :     if( ImplIsRecordLayout() )
    1017                 :          0 :         return;
    1018                 :            : 
    1019         [ #  # ]:          0 :     ImplDrawMask( rDestPt, rDestSize, Point(), rBitmap.GetSizePixel(), rBitmap, rMaskColor, META_MASKSCALE_ACTION );
    1020                 :            : 
    1021                 :            :     // TODO: Use mask here
    1022         [ #  # ]:          0 :     if( mpAlphaVDev )
    1023                 :            :     {
    1024                 :          0 :         const Bitmap& rMask( rBitmap.CreateMask( rMaskColor ) );
    1025                 :            : 
    1026                 :            :         // #i25167# Restrict mask painting to _opaque_ areas
    1027                 :            :         // of the mask, otherwise we spoil areas where no
    1028                 :            :         // bitmap content was ever visible. Interestingly
    1029                 :            :         // enough, this can be achieved by taking the mask as
    1030                 :            :         // the transparency mask of itself
    1031                 :            :         mpAlphaVDev->DrawBitmapEx( rDestPt,
    1032                 :            :                                    rDestSize,
    1033 [ #  # ][ #  # ]:          0 :                                    BitmapEx( rMask, rMask ) );
                 [ #  # ]
    1034                 :            :     }
    1035                 :            : }
    1036                 :            : 
    1037                 :          0 : void OutputDevice::DrawMask( const Point& rDestPt, const Size& rDestSize,
    1038                 :            :                              const Point& rSrcPtPixel, const Size& rSrcSizePixel,
    1039                 :            :                              const Bitmap& rBitmap, const Color& rMaskColor )
    1040                 :            : {
    1041                 :            :     OSL_TRACE( "OutputDevice::DrawMask( Point, Size )" );
    1042                 :            : 
    1043         [ #  # ]:          0 :     if( ImplIsRecordLayout() )
    1044                 :          0 :         return;
    1045                 :            : 
    1046                 :          0 :     ImplDrawMask( rDestPt, rDestSize, rSrcPtPixel, rSrcSizePixel, rBitmap, rMaskColor, META_MASKSCALEPART_ACTION );
    1047                 :            : 
    1048                 :            :     // TODO: Use mask here
    1049         [ #  # ]:          0 :     if( mpAlphaVDev )
    1050                 :            :     {
    1051                 :          0 :         const Bitmap& rMask( rBitmap.CreateMask( rMaskColor ) );
    1052                 :            : 
    1053                 :            :         // #i25167# Restrict mask painting to _opaque_ areas
    1054                 :            :         // of the mask, otherwise we spoil areas where no
    1055                 :            :         // bitmap content was ever visible. Interestingly
    1056                 :            :         // enough, this can be achieved by taking the mask as
    1057                 :            :         // the transparency mask of itself
    1058                 :            :         mpAlphaVDev->DrawBitmapEx( rDestPt,
    1059                 :            :                                    rDestSize,
    1060                 :            :                                    rSrcPtPixel,
    1061                 :            :                                    rSrcSizePixel,
    1062 [ #  # ][ #  # ]:          0 :                                    BitmapEx( rMask, rMask ) );
                 [ #  # ]
    1063                 :            :     }
    1064                 :            : }
    1065                 :            : 
    1066                 :          0 : void OutputDevice::ImplDrawMask( const Point& rDestPt, const Size& rDestSize,
    1067                 :            :                                  const Point& rSrcPtPixel, const Size& rSrcSizePixel,
    1068                 :            :                                  const Bitmap& rBitmap, const Color& rMaskColor,
    1069                 :            :                                  const sal_uLong nAction )
    1070                 :            : {
    1071                 :            :     DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
    1072                 :            : 
    1073         [ #  # ]:          0 :     if( ROP_INVERT == meRasterOp )
    1074                 :            :     {
    1075         [ #  # ]:          0 :         DrawRect( Rectangle( rDestPt, rDestSize ) );
    1076                 :          0 :         return;
    1077                 :            :     }
    1078                 :            : 
    1079         [ #  # ]:          0 :     if ( mpMetaFile )
    1080                 :            :     {
    1081   [ #  #  #  # ]:          0 :         switch( nAction )
    1082                 :            :         {
    1083                 :            :             case( META_MASK_ACTION ):
    1084                 :            :                 mpMetaFile->AddAction( new MetaMaskAction( rDestPt,
    1085         [ #  # ]:          0 :                     rBitmap, rMaskColor ) );
    1086                 :          0 :             break;
    1087                 :            : 
    1088                 :            :             case( META_MASKSCALE_ACTION ):
    1089                 :            :                 mpMetaFile->AddAction( new MetaMaskScaleAction( rDestPt,
    1090         [ #  # ]:          0 :                     rDestSize, rBitmap, rMaskColor ) );
    1091                 :          0 :             break;
    1092                 :            : 
    1093                 :            :             case( META_MASKSCALEPART_ACTION ):
    1094                 :            :                 mpMetaFile->AddAction( new MetaMaskScalePartAction( rDestPt, rDestSize,
    1095         [ #  # ]:          0 :                     rSrcPtPixel, rSrcSizePixel, rBitmap, rMaskColor ) );
    1096                 :          0 :             break;
    1097                 :            :         }
    1098                 :            :     }
    1099                 :            : 
    1100 [ #  # ][ #  # ]:          0 :     OUTDEV_INIT();
         [ #  # ][ #  # ]
                 [ #  # ]
    1101                 :            : 
    1102         [ #  # ]:          0 :     if ( OUTDEV_PRINTER == meOutDevType )
    1103                 :            :     {
    1104                 :          0 :         ImplPrintMask( rBitmap, rMaskColor, rDestPt, rDestSize, rSrcPtPixel, rSrcSizePixel );
    1105                 :          0 :         return;
    1106                 :            :     }
    1107                 :            : 
    1108                 :          0 :     const ImpBitmap* pImpBmp = rBitmap.ImplGetImpBitmap();
    1109         [ #  # ]:          0 :     if ( pImpBmp )
    1110                 :            :     {
    1111                 :            :         SalTwoRect aPosAry;
    1112                 :            : 
    1113                 :          0 :         aPosAry.mnSrcX = rSrcPtPixel.X();
    1114                 :          0 :         aPosAry.mnSrcY = rSrcPtPixel.Y();
    1115                 :          0 :         aPosAry.mnSrcWidth = rSrcSizePixel.Width();
    1116                 :          0 :         aPosAry.mnSrcHeight = rSrcSizePixel.Height();
    1117         [ #  # ]:          0 :         aPosAry.mnDestX = ImplLogicXToDevicePixel( rDestPt.X() );
    1118         [ #  # ]:          0 :         aPosAry.mnDestY = ImplLogicYToDevicePixel( rDestPt.Y() );
    1119         [ #  # ]:          0 :         aPosAry.mnDestWidth = ImplLogicWidthToDevicePixel( rDestSize.Width() );
    1120         [ #  # ]:          0 :         aPosAry.mnDestHeight = ImplLogicHeightToDevicePixel( rDestSize.Height() );
    1121                 :            : 
    1122                 :            :         // we don't want to mirror via cooridates
    1123 [ #  # ][ #  # ]:          0 :         const sal_uLong nMirrFlags = ImplAdjustTwoRect( aPosAry, pImpBmp->ImplGetSize() );
    1124                 :            : 
    1125                 :            :         // check if output is necessary
    1126 [ #  # ][ #  # ]:          0 :         if( aPosAry.mnSrcWidth && aPosAry.mnSrcHeight && aPosAry.mnDestWidth && aPosAry.mnDestHeight )
         [ #  # ][ #  # ]
    1127                 :            :         {
    1128                 :            : 
    1129         [ #  # ]:          0 :             if( nMirrFlags )
    1130                 :            :             {
    1131         [ #  # ]:          0 :                 Bitmap aTmp( rBitmap );
    1132         [ #  # ]:          0 :                 aTmp.Mirror( nMirrFlags );
    1133         [ #  # ]:          0 :                 mpGraphics->DrawMask( &aPosAry, *aTmp.ImplGetImpBitmap()->ImplGetSalBitmap(),
    1134 [ #  # ][ #  # ]:          0 :                                       ImplColorToSal( rMaskColor ) , this);
    1135                 :            :             }
    1136                 :            :             else
    1137                 :          0 :                 mpGraphics->DrawMask( &aPosAry, *pImpBmp->ImplGetSalBitmap(),
    1138         [ #  # ]:          0 :                                       ImplColorToSal( rMaskColor ), this );
    1139                 :            : 
    1140                 :            :         }
    1141                 :            :     }
    1142                 :            : }
    1143                 :            : 
    1144                 :            : namespace
    1145                 :            : {
    1146                 :          8 :     BitmapEx makeDisabledBitmap(const Bitmap &rBitmap)
    1147                 :            :     {
    1148         [ +  - ]:          8 :         const Size aTotalSize( rBitmap.GetSizePixel() );
    1149 [ +  - ][ +  - ]:          8 :         Bitmap aGrey( aTotalSize, 8, &Bitmap::GetGreyPalette( 256 ) );
    1150         [ +  - ]:          8 :         AlphaMask aGreyAlphaMask( aTotalSize );
    1151         [ +  - ]:          8 :         BitmapReadAccess*  pBmp = const_cast<Bitmap&>(rBitmap).AcquireReadAccess();
    1152         [ +  - ]:          8 :         BitmapWriteAccess* pGrey = aGrey.AcquireWriteAccess();
    1153         [ +  - ]:          8 :         BitmapWriteAccess* pGreyAlphaMask = aGreyAlphaMask.AcquireWriteAccess();
    1154                 :            : 
    1155 [ +  - ][ +  - ]:          8 :         if( pBmp && pGrey && pGreyAlphaMask )
                 [ +  - ]
    1156                 :            :         {
    1157                 :          8 :             BitmapColor aGreyVal( 0 );
    1158                 :          8 :             BitmapColor aGreyAlphaMaskVal( 0 );
    1159                 :          8 :             const int nLeft = 0, nRight = aTotalSize.Width();
    1160                 :          8 :             const int nTop = 0, nBottom = nTop + aTotalSize.Height();
    1161                 :            : 
    1162         [ +  + ]:        136 :             for( int nY = nTop; nY < nBottom; ++nY )
    1163                 :            :             {
    1164         [ +  + ]:       2176 :                 for( int nX = nLeft; nX < nRight; ++nX )
    1165                 :            :                 {
    1166         [ +  - ]:       2048 :                     aGreyVal.SetIndex( pBmp->GetLuminance( nY, nX ) );
    1167         [ +  - ]:       2048 :                     pGrey->SetPixel( nY, nX, aGreyVal );
    1168                 :            : 
    1169                 :       2048 :                     aGreyAlphaMaskVal.SetIndex( static_cast< sal_uInt8 >( 128ul ) );
    1170         [ +  - ]:       2048 :                     pGreyAlphaMask->SetPixel( nY, nX, aGreyAlphaMaskVal );
    1171                 :            :                 }
    1172                 :          8 :             }
    1173                 :            :         }
    1174                 :            : 
    1175         [ +  - ]:          8 :         const_cast<Bitmap&>(rBitmap).ReleaseAccess( pBmp );
    1176         [ +  - ]:          8 :         aGrey.ReleaseAccess( pGrey );
    1177         [ +  - ]:          8 :         aGreyAlphaMask.ReleaseAccess( pGreyAlphaMask );
    1178 [ +  - ][ +  - ]:          8 :         return BitmapEx( aGrey, aGreyAlphaMask );
                 [ +  - ]
    1179                 :            :     }
    1180                 :            : }
    1181                 :            : 
    1182                 :     126317 : void OutputDevice::DrawImage( const Point& rPos, const Image& rImage, sal_uInt16 nStyle )
    1183                 :            : {
    1184                 :            :     DBG_ASSERT( GetOutDevType() != OUTDEV_PRINTER, "DrawImage(): Images can't be drawn on any mprinter" );
    1185                 :            : 
    1186 [ +  + ][ +  + ]:     126317 :     if( !rImage.mpImplData || ImplIsRecordLayout() )
                 [ +  + ]
    1187                 :     126317 :         return;
    1188                 :            : 
    1189      [ +  +  - ]:     121363 :     switch( rImage.mpImplData->meType )
    1190                 :            :     {
    1191                 :            :         case IMAGETYPE_BITMAP:
    1192                 :            :         {
    1193                 :       2153 :             const Bitmap &rBitmap = *static_cast< Bitmap* >( rImage.mpImplData->mpData );
    1194         [ +  + ]:       2153 :             if( nStyle & IMAGE_DRAW_DISABLE )
    1195         [ +  - ]:          8 :                 DrawBitmapEx( rPos, makeDisabledBitmap(rBitmap) );
    1196                 :            :             else
    1197                 :       2145 :                 DrawBitmap( rPos, rBitmap );
    1198                 :            :         }
    1199                 :       2153 :         break;
    1200                 :            : 
    1201                 :            :         case IMAGETYPE_IMAGE:
    1202                 :            :         {
    1203                 :     119210 :             ImplImageData* pData = static_cast< ImplImageData* >( rImage.mpImplData->mpData );
    1204                 :            : 
    1205         [ +  + ]:     119210 :             if( !pData->mpImageBitmap )
    1206                 :            :             {
    1207                 :      61398 :                 const Size aSize( pData->maBmpEx.GetSizePixel() );
    1208                 :            : 
    1209 [ +  - ][ +  - ]:      61398 :                 pData->mpImageBitmap = new ImplImageBmp;
    1210         [ +  - ]:      61398 :                 pData->mpImageBitmap->Create( pData->maBmpEx, aSize.Width(), aSize.Height(), 1 );
    1211                 :            :             }
    1212                 :            : 
    1213                 :     119210 :             pData->mpImageBitmap->Draw( 0, this, rPos, nStyle );
    1214                 :            :         }
    1215                 :     119210 :         break;
    1216                 :            : 
    1217                 :            :         default:
    1218                 :          0 :         break;
    1219                 :            :     }
    1220                 :            : }
    1221                 :            : 
    1222                 :          0 : void OutputDevice::DrawImage( const Point& rPos, const Size& rSize,
    1223                 :            :                               const Image& rImage, sal_uInt16 nStyle )
    1224                 :            : {
    1225                 :            :     DBG_ASSERT( GetOutDevType() != OUTDEV_PRINTER, "DrawImage(): Images can't be drawn on any mprinter" );
    1226                 :            : 
    1227 [ #  # ][ #  # ]:          0 :     if( rImage.mpImplData && !ImplIsRecordLayout() )
                 [ #  # ]
    1228                 :            :     {
    1229      [ #  #  # ]:          0 :         switch( rImage.mpImplData->meType )
    1230                 :            :         {
    1231                 :            :             case IMAGETYPE_BITMAP:
    1232                 :            :             {
    1233                 :          0 :                 const Bitmap &rBitmap = *static_cast< Bitmap* >( rImage.mpImplData->mpData );
    1234         [ #  # ]:          0 :                 if( nStyle & IMAGE_DRAW_DISABLE )
    1235         [ #  # ]:          0 :                     DrawBitmapEx( rPos, rSize, makeDisabledBitmap(rBitmap) );
    1236                 :            :                 else
    1237                 :          0 :                     DrawBitmap( rPos, rSize, rBitmap );
    1238                 :            :             }
    1239                 :          0 :             break;
    1240                 :            : 
    1241                 :            :             case IMAGETYPE_IMAGE:
    1242                 :            :             {
    1243                 :          0 :                 ImplImageData* pData = static_cast< ImplImageData* >( rImage.mpImplData->mpData );
    1244                 :            : 
    1245         [ #  # ]:          0 :                 if ( !pData->mpImageBitmap )
    1246                 :            :                 {
    1247                 :          0 :                     const Size aSize( pData->maBmpEx.GetSizePixel() );
    1248                 :            : 
    1249 [ #  # ][ #  # ]:          0 :                     pData->mpImageBitmap = new ImplImageBmp;
    1250         [ #  # ]:          0 :                     pData->mpImageBitmap->Create( pData->maBmpEx, aSize.Width(), aSize.Height(), 1 );
    1251                 :            :                 }
    1252                 :            : 
    1253                 :          0 :                 pData->mpImageBitmap->Draw( 0, this, rPos, nStyle, &rSize );
    1254                 :            :             }
    1255                 :          0 :             break;
    1256                 :            : 
    1257                 :            :             default:
    1258                 :          0 :             break;
    1259                 :            :         }
    1260                 :            :     }
    1261                 :          0 : }
    1262                 :            : 
    1263                 :     221537 : Bitmap OutputDevice::GetBitmap( const Point& rSrcPt, const Size& rSize ) const
    1264                 :            : {
    1265                 :            :     DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
    1266                 :            : 
    1267                 :     221537 :     Bitmap  aBmp;
    1268         [ +  - ]:     221537 :     long    nX = ImplLogicXToDevicePixel( rSrcPt.X() );
    1269         [ +  - ]:     221537 :     long    nY = ImplLogicYToDevicePixel( rSrcPt.Y() );
    1270         [ +  - ]:     221537 :     long    nWidth = ImplLogicWidthToDevicePixel( rSize.Width() );
    1271         [ +  - ]:     221537 :     long    nHeight = ImplLogicHeightToDevicePixel( rSize.Height() );
    1272                 :            : 
    1273 [ -  + ][ #  # ]:     221537 :     if ( mpGraphics || ( (OutputDevice*) this )->ImplGetGraphics() )
         [ #  # ][ +  - ]
    1274                 :            :     {
    1275 [ +  + ][ +  + ]:     221537 :         if ( nWidth && nHeight )
    1276                 :            :         {
    1277         [ +  - ]:     221121 :             Rectangle   aRect( Point( nX, nY ), Size( nWidth, nHeight ) );
    1278                 :     221121 :             bool        bClipped = false;
    1279                 :            : 
    1280                 :            :             // X-Coordinate outside of draw area?
    1281         [ +  + ]:     221121 :             if ( nX < mnOutOffX )
    1282                 :            :             {
    1283                 :        138 :                 nWidth -= ( mnOutOffX - nX );
    1284                 :        138 :                 nX = mnOutOffX;
    1285                 :        138 :                 bClipped = true;
    1286                 :            :             }
    1287                 :            : 
    1288                 :            :             // Y-Coordinate outside of draw area?
    1289         [ +  + ]:     221121 :             if ( nY < mnOutOffY )
    1290                 :            :             {
    1291                 :       8284 :                 nHeight -= ( mnOutOffY - nY );
    1292                 :       8284 :                 nY = mnOutOffY;
    1293                 :       8284 :                 bClipped = true;
    1294                 :            :             }
    1295                 :            : 
    1296                 :            :             // Width outside of draw area?
    1297         [ -  + ]:     221121 :             if ( (nWidth + nX) > (mnOutWidth + mnOutOffX) )
    1298                 :            :             {
    1299                 :          0 :                 nWidth  = mnOutOffX + mnOutWidth - nX;
    1300                 :          0 :                 bClipped = true;
    1301                 :            :             }
    1302                 :            : 
    1303                 :            :             // Height outside of draw area?
    1304         [ -  + ]:     221121 :             if ( (nHeight + nY) > (mnOutHeight + mnOutOffY) )
    1305                 :            :             {
    1306                 :          0 :                 nHeight = mnOutOffY + mnOutHeight - nY;
    1307                 :          0 :                 bClipped = true;
    1308                 :            :             }
    1309                 :            : 
    1310         [ +  + ]:     221121 :             if ( bClipped )
    1311                 :            :             {
    1312                 :            :                 // If the visible part has been clipped, we have to create a
    1313                 :            :                 // Bitmap with the correct size in which we copy the clipped
    1314                 :            :                 // Bitmap to the correct position.
    1315         [ +  - ]:       8348 :                 VirtualDevice aVDev( *this );
    1316                 :            : 
    1317 [ +  - ][ +  - ]:       8348 :                 if ( aVDev.SetOutputSizePixel( aRect.GetSize() ) )
                 [ +  - ]
    1318                 :            :                 {
    1319 [ -  + ][ #  # ]:       8348 :                     if ( ((OutputDevice*)&aVDev)->mpGraphics || ((OutputDevice*)&aVDev)->ImplGetGraphics() )
         [ #  # ][ +  - ]
    1320                 :            :                     {
    1321                 :            :                         SalTwoRect aPosAry;
    1322                 :            : 
    1323                 :       8348 :                         aPosAry.mnSrcX = nX;
    1324                 :       8348 :                         aPosAry.mnSrcY = nY;
    1325                 :       8348 :                         aPosAry.mnSrcWidth = nWidth;
    1326                 :       8348 :                         aPosAry.mnSrcHeight = nHeight;
    1327         [ +  + ]:       8348 :                         aPosAry.mnDestX = ( aRect.Left() < mnOutOffX ) ? ( mnOutOffX - aRect.Left() ) : 0L;
    1328         [ +  + ]:       8348 :                         aPosAry.mnDestY = ( aRect.Top() < mnOutOffY ) ? ( mnOutOffY - aRect.Top() ) : 0L;
    1329                 :       8348 :                         aPosAry.mnDestWidth = nWidth;
    1330                 :       8348 :                         aPosAry.mnDestHeight = nHeight;
    1331                 :            : 
    1332 [ +  + ][ +  + ]:       8348 :                         if ( (nWidth > 0) && (nHeight > 0) )
    1333         [ +  - ]:         12 :                             (((OutputDevice*)&aVDev)->mpGraphics)->CopyBits( &aPosAry, mpGraphics, this, this );
    1334                 :            : 
    1335 [ +  - ][ +  - ]:       8348 :                         aBmp = aVDev.GetBitmap( Point(), aVDev.GetOutputSizePixel() );
                 [ +  - ]
    1336                 :            :                      }
    1337                 :            :                      else
    1338                 :          0 :                         bClipped = false;
    1339                 :            :                 }
    1340                 :            :                 else
    1341         [ +  - ]:       8348 :                     bClipped = false;
    1342                 :            :             }
    1343                 :            : 
    1344         [ +  + ]:     221121 :             if ( !bClipped )
    1345                 :            :             {
    1346         [ +  - ]:     212773 :                 SalBitmap* pSalBmp = mpGraphics->GetBitmap( nX, nY, nWidth, nHeight, this );
    1347                 :            : 
    1348         [ +  - ]:     212773 :                 if( pSalBmp )
    1349                 :            :                 {
    1350 [ +  - ][ +  - ]:     212773 :                     ImpBitmap* pImpBmp = new ImpBitmap;
    1351         [ +  - ]:     212773 :                     pImpBmp->ImplSetSalBitmap( pSalBmp );
    1352         [ +  - ]:     221121 :                     aBmp.ImplSetImpBitmap( pImpBmp );
    1353                 :            :                 }
    1354                 :            :             }
    1355                 :            :         }
    1356                 :            :     }
    1357                 :            : 
    1358                 :     221537 :     return aBmp;
    1359                 :            : }
    1360                 :            : 
    1361                 :      10762 : BitmapEx OutputDevice::GetBitmapEx( const Point& rSrcPt, const Size& rSize ) const
    1362                 :            : {
    1363                 :            :     DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
    1364                 :            : 
    1365                 :            :     // #110958# Extract alpha value from VDev, if any
    1366         [ +  - ]:      10762 :     if( mpAlphaVDev )
    1367                 :            :     {
    1368         [ +  - ]:      10762 :         Bitmap aAlphaBitmap( mpAlphaVDev->GetBitmap( rSrcPt, rSize ) );
    1369                 :            : 
    1370                 :            :         // ensure 8 bit alpha
    1371 [ +  - ][ +  + ]:      10762 :         if( aAlphaBitmap.GetBitCount() > 8 )
    1372         [ +  - ]:      10691 :             aAlphaBitmap.Convert( BMP_CONVERSION_8BIT_GREYS );
    1373                 :            : 
    1374 [ +  - ][ +  - ]:      10762 :         return BitmapEx(GetBitmap( rSrcPt, rSize ), AlphaMask( aAlphaBitmap ) );
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
    1375                 :            :     }
    1376                 :            :     else
    1377         [ #  # ]:      10762 :         return GetBitmap( rSrcPt, rSize );
    1378                 :            : }
    1379                 :            : 
    1380                 :          0 : Color OutputDevice::GetPixel( const Point& rPt ) const
    1381                 :            : {
    1382                 :            :     DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
    1383                 :            : 
    1384                 :          0 :     Color aColor;
    1385                 :            : 
    1386 [ #  # ][ #  # ]:          0 :     if ( mpGraphics || ((OutputDevice*)this)->ImplGetGraphics() )
                 [ #  # ]
    1387                 :            :     {
    1388         [ #  # ]:          0 :         if ( mbInitClipRegion )
    1389                 :          0 :             ((OutputDevice*)this)->ImplInitClipRegion();
    1390                 :            : 
    1391         [ #  # ]:          0 :         if ( !mbOutputClipped )
    1392                 :            :         {
    1393                 :          0 :             const long      nX = ImplLogicXToDevicePixel( rPt.X() );
    1394                 :          0 :             const long      nY = ImplLogicYToDevicePixel( rPt.Y() );
    1395                 :          0 :             const SalColor  aSalCol = mpGraphics->GetPixel( nX, nY, this );
    1396                 :          0 :             aColor.SetRed( SALCOLOR_RED( aSalCol ) );
    1397                 :          0 :             aColor.SetGreen( SALCOLOR_GREEN( aSalCol ) );
    1398                 :          0 :             aColor.SetBlue( SALCOLOR_BLUE( aSalCol ) );
    1399                 :            :         }
    1400                 :            :     }
    1401                 :          0 :     return aColor;
    1402                 :            : }
    1403                 :            : 
    1404                 :      38203 : void OutputDevice::DrawPixel( const Point& rPt )
    1405                 :            : {
    1406                 :            :     OSL_TRACE( "OutputDevice::DrawPixel()" );
    1407                 :            :     DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
    1408                 :            : 
    1409         [ +  + ]:      38203 :     if ( mpMetaFile )
    1410 [ +  - ][ +  - ]:       3012 :         mpMetaFile->AddAction( new MetaPointAction( rPt ) );
                 [ +  - ]
    1411                 :            : 
    1412 [ +  - ][ +  - ]:      38203 :     if ( !IsDeviceOutputNecessary() || !mbLineColor || ImplIsRecordLayout() )
         [ +  - ][ -  + ]
                 [ +  - ]
    1413                 :            :         return;
    1414                 :            : 
    1415         [ +  - ]:      38203 :     Point aPt = ImplLogicToDevicePixel( rPt );
    1416                 :            : 
    1417         [ -  + ]:      38203 :     if ( !mpGraphics )
    1418                 :            :     {
    1419 [ #  # ][ #  # ]:          0 :         if ( !ImplGetGraphics() )
    1420                 :            :             return;
    1421                 :            :     }
    1422                 :            : 
    1423         [ +  + ]:      38203 :     if ( mbInitClipRegion )
    1424         [ +  - ]:      10401 :         ImplInitClipRegion();
    1425         [ +  + ]:      38203 :     if ( mbOutputClipped )
    1426                 :            :         return;
    1427                 :            : 
    1428         [ +  + ]:      35071 :     if ( mbInitLineColor )
    1429         [ +  - ]:      27939 :         ImplInitLineColor();
    1430                 :            : 
    1431         [ +  - ]:      35071 :     mpGraphics->DrawPixel( aPt.X(), aPt.Y(), this );
    1432                 :            : 
    1433         [ +  + ]:      35071 :     if( mpAlphaVDev )
    1434         [ +  - ]:      38203 :         mpAlphaVDev->DrawPixel( rPt );
    1435                 :            : }
    1436                 :            : 
    1437                 :     307918 : void OutputDevice::DrawPixel( const Point& rPt, const Color& rColor )
    1438                 :            : {
    1439                 :            :     OSL_TRACE( "OutputDevice::DrawPixel()" );
    1440                 :            :     DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
    1441                 :            : 
    1442         [ +  - ]:     307918 :     Color aColor = ImplDrawModeToColor( rColor );
    1443                 :            : 
    1444         [ -  + ]:     307918 :     if ( mpMetaFile )
    1445 [ #  # ][ #  # ]:          0 :         mpMetaFile->AddAction( new MetaPixelAction( rPt, aColor ) );
                 [ #  # ]
    1446                 :            : 
    1447 [ +  - ][ +  - ]:     307918 :     if ( !IsDeviceOutputNecessary() || ImplIsColorTransparent( aColor ) || ImplIsRecordLayout() )
         [ +  - ][ -  + ]
                 [ +  - ]
    1448                 :            :         return;
    1449                 :            : 
    1450         [ +  - ]:     307918 :     Point aPt = ImplLogicToDevicePixel( rPt );
    1451                 :            : 
    1452         [ -  + ]:     307918 :     if ( !mpGraphics )
    1453                 :            :     {
    1454 [ #  # ][ #  # ]:          0 :         if ( !ImplGetGraphics() )
    1455                 :            :             return;
    1456                 :            :     }
    1457                 :            : 
    1458         [ +  + ]:     307918 :     if ( mbInitClipRegion )
    1459         [ +  - ]:       8123 :         ImplInitClipRegion();
    1460         [ +  - ]:     307918 :     if ( mbOutputClipped )
    1461                 :            :         return;
    1462                 :            : 
    1463         [ +  - ]:     307918 :     mpGraphics->DrawPixel( aPt.X(), aPt.Y(), ImplColorToSal( aColor ), this );
    1464                 :            : 
    1465         [ -  + ]:     307918 :     if( mpAlphaVDev )
    1466         [ #  # ]:     307918 :         mpAlphaVDev->DrawPixel( rPt );
    1467                 :            : }
    1468                 :            : 
    1469                 :          0 : void OutputDevice::DrawPixel( const Polygon& rPts, const Color* pColors )
    1470                 :            : {
    1471         [ #  # ]:          0 :     if ( !pColors )
    1472                 :          0 :         DrawPixel( rPts, GetLineColor() );
    1473                 :            :     else
    1474                 :            :     {
    1475                 :            :         OSL_TRACE( "OutputDevice::DrawPixel()" );
    1476                 :            :         DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
    1477                 :            :         DBG_ASSERT( pColors, "OutputDevice::DrawPixel: No color array specified" );
    1478                 :            : 
    1479                 :          0 :         const sal_uInt16 nSize = rPts.GetSize();
    1480                 :            : 
    1481         [ #  # ]:          0 :         if ( nSize )
    1482                 :            :         {
    1483         [ #  # ]:          0 :             if ( mpMetaFile )
    1484         [ #  # ]:          0 :                 for ( sal_uInt16 i = 0; i < nSize; i++ )
    1485         [ #  # ]:          0 :                     mpMetaFile->AddAction( new MetaPixelAction( rPts[ i ], pColors[ i ] ) );
    1486                 :            : 
    1487 [ #  # ][ #  # ]:          0 :             if ( !IsDeviceOutputNecessary() || ImplIsRecordLayout() )
                 [ #  # ]
    1488                 :          0 :                 return;
    1489                 :            : 
    1490 [ #  # ][ #  # ]:          0 :             if ( mpGraphics || ImplGetGraphics() )
                 [ #  # ]
    1491                 :            :             {
    1492         [ #  # ]:          0 :                 if ( mbInitClipRegion )
    1493                 :          0 :                     ImplInitClipRegion();
    1494                 :            : 
    1495         [ #  # ]:          0 :                 if ( mbOutputClipped )
    1496                 :          0 :                     return;
    1497                 :            : 
    1498         [ #  # ]:          0 :                 for ( sal_uInt16 i = 0; i < nSize; i++ )
    1499                 :            :                 {
    1500 [ #  # ][ #  # ]:          0 :                     const Point aPt( ImplLogicToDevicePixel( rPts[ i ] ) );
    1501         [ #  # ]:          0 :                     mpGraphics->DrawPixel( aPt.X(), aPt.Y(), ImplColorToSal( pColors[ i ] ), this );
    1502                 :            :                 }
    1503                 :            :             }
    1504                 :            :         }
    1505                 :            :     }
    1506                 :            : 
    1507         [ #  # ]:          0 :     if( mpAlphaVDev )
    1508                 :          0 :         mpAlphaVDev->DrawPixel( rPts, pColors );
    1509                 :            : }
    1510                 :            : 
    1511                 :          0 : void OutputDevice::DrawPixel( const Polygon& rPts, const Color& rColor )
    1512                 :            : {
    1513 [ #  # ][ #  # ]:          0 :     if( rColor != COL_TRANSPARENT && ! ImplIsRecordLayout() )
         [ #  # ][ #  # ]
           [ #  #  #  # ]
    1514                 :            :     {
    1515                 :          0 :         const sal_uInt16    nSize = rPts.GetSize();
    1516         [ #  # ]:          0 :         Color*          pColArray = new Color[ nSize ];
    1517                 :            : 
    1518         [ #  # ]:          0 :         for( sal_uInt16 i = 0; i < nSize; i++ )
    1519                 :          0 :             pColArray[ i ] = rColor;
    1520                 :            : 
    1521                 :          0 :         DrawPixel( rPts, pColArray );
    1522         [ #  # ]:          0 :         delete[] pColArray;
    1523                 :            :     }
    1524                 :            : 
    1525         [ #  # ]:          0 :     if( mpAlphaVDev )
    1526                 :          0 :         mpAlphaVDev->DrawPixel( rPts, rColor );
    1527                 :          0 : }
    1528                 :            : 
    1529                 :            : namespace
    1530                 :            : {
    1531                 :            :     // Co = Cs + Cd*(1-As) premultiplied alpha -or-
    1532                 :            :     // Co = (AsCs + AdCd*(1-As)) / Ao
    1533                 :     111141 :     inline sal_uInt8 lcl_calcColor( const sal_uInt8 nSourceColor, const sal_uInt8 nSourceAlpha,
    1534                 :            :                                     const sal_uInt8 nDstAlpha, const sal_uInt8 nResAlpha, const sal_uInt8 nDestColor )
    1535                 :            :     {
    1536                 :            :         int c = nResAlpha ? ( (int)nSourceAlpha*nSourceColor + (int)nDstAlpha*nDestColor -
    1537         [ +  + ]:     111141 :                               (int)nDstAlpha*nDestColor*nSourceAlpha/255 ) / (int)nResAlpha : 0;
    1538                 :     111141 :         return sal_uInt8( c );
    1539                 :            :     }
    1540                 :            : 
    1541                 :      37047 : inline BitmapColor lcl_AlphaBlend( int nX,               int nY,
    1542                 :            :                                    const long            nMapX,
    1543                 :            :                                    const long            nMapY,
    1544                 :            :                                    BitmapReadAccess*     pP,
    1545                 :            :                                    BitmapReadAccess*     pA,
    1546                 :            :                                    BitmapReadAccess*     pB,
    1547                 :            :                                    BitmapWriteAccess*    pAlphaW,
    1548                 :            :                                    sal_uInt8&            nResAlpha )
    1549                 :            : {
    1550                 :      37047 :     BitmapColor aDstCol,aSrcCol;
    1551         [ +  - ]:      37047 :     aSrcCol = pP->GetColor( nMapY, nMapX );
    1552         [ +  - ]:      37047 :     aDstCol = pB->GetColor( nY, nX );
    1553                 :            : 
    1554                 :            :     // vcl stores transparency, not alpha - invert it
    1555         [ +  - ]:      37047 :     const sal_uInt8 nSrcAlpha = 255 - pA->GetPixel( nMapY, nMapX ).GetBlueOrIndex();
    1556         [ +  - ]:      37047 :     const sal_uInt8 nDstAlpha = 255 - pAlphaW->GetPixel( nY, nX ).GetBlueOrIndex();
    1557                 :            : 
    1558                 :            :     // Perform porter-duff compositing 'over' operation
    1559                 :            :     //
    1560                 :            :     // Co = Cs + Cd*(1-As)
    1561                 :            :     // Ad = As + Ad*(1-As)
    1562                 :      37047 :     nResAlpha = (int)nSrcAlpha + (int)nDstAlpha - (int)nDstAlpha*nSrcAlpha/255;
    1563                 :            : 
    1564                 :      37047 :     aDstCol.SetRed( lcl_calcColor( aSrcCol.GetRed(), nSrcAlpha, nDstAlpha, nResAlpha, aDstCol.GetRed() ) );
    1565                 :      37047 :     aDstCol.SetBlue( lcl_calcColor( aSrcCol.GetBlue(), nSrcAlpha, nDstAlpha, nResAlpha, aDstCol.GetBlue() ) );
    1566                 :      37047 :     aDstCol.SetGreen( lcl_calcColor( aSrcCol.GetGreen(), nSrcAlpha, nDstAlpha, nResAlpha, aDstCol.GetGreen() ) );
    1567                 :            : 
    1568                 :      37047 :     return aDstCol;
    1569                 :            : }
    1570                 :            : }
    1571                 :            : 
    1572                 :         86 : Bitmap OutputDevice::ImplBlendWithAlpha( Bitmap              aBmp,
    1573                 :            :                                          BitmapReadAccess*   pP,
    1574                 :            :                                          BitmapReadAccess*   pA,
    1575                 :            :                                          const Rectangle&    aDstRect,
    1576                 :            :                                          const sal_Int32     nOffY,
    1577                 :            :                                          const sal_Int32     nDstHeight,
    1578                 :            :                                          const sal_Int32     nOffX,
    1579                 :            :                                          const sal_Int32     nDstWidth,
    1580                 :            :                                          const long*         pMapX,
    1581                 :            :                                          const long*         pMapY )
    1582                 :            : {
    1583                 :         86 :     BitmapColor aDstCol;
    1584         [ +  - ]:         86 :     Bitmap      res;
    1585                 :            :     int         nX, nY;
    1586                 :            :     sal_uInt8   nResAlpha;
    1587                 :            : 
    1588                 :            :     OSL_ENSURE(mpAlphaVDev,
    1589                 :            :                "ImplBlendWithAlpha(): call me only with valid alpha VDev!" );
    1590                 :            : 
    1591                 :         86 :     bool bOldMapMode( mpAlphaVDev->IsMapModeEnabled() );
    1592         [ +  - ]:         86 :     mpAlphaVDev->EnableMapMode(sal_False);
    1593                 :            : 
    1594 [ +  - ][ +  - ]:         86 :     Bitmap aAlphaBitmap( mpAlphaVDev->GetBitmap( aDstRect.TopLeft(), aDstRect.GetSize() ) );
    1595         [ +  - ]:         86 :     BitmapWriteAccess*  pAlphaW = aAlphaBitmap.AcquireWriteAccess();
    1596                 :            : 
    1597 [ +  - ][ -  + ]:         86 :     if( GetBitCount() <= 8 )
    1598                 :            :     {
    1599 [ #  # ][ #  # ]:          0 :         Bitmap              aDither( aBmp.GetSizePixel(), 8 );
    1600                 :          0 :         BitmapColor         aIndex( 0 );
    1601         [ #  # ]:          0 :         BitmapReadAccess*   pB = aBmp.AcquireReadAccess();
    1602         [ #  # ]:          0 :         BitmapWriteAccess*  pW = aDither.AcquireWriteAccess();
    1603                 :            : 
    1604 [ #  # ][ #  # ]:          0 :         if( pB && pP && pA && pW && pAlphaW )
         [ #  # ][ #  # ]
                 [ #  # ]
    1605                 :            :         {
    1606                 :            :             int nOutY;
    1607                 :            : 
    1608         [ #  # ]:          0 :             for( nY = 0, nOutY = nOffY; nY < nDstHeight; nY++, nOutY++ )
    1609                 :            :             {
    1610                 :          0 :                 const long nMapY = pMapY[ nY ];
    1611                 :          0 :                 const long nModY = ( nOutY & 0x0FL ) << 4L;
    1612                 :            :                 int nOutX;
    1613                 :            : 
    1614         [ #  # ]:          0 :                 for( nX = 0, nOutX = nOffX; nX < nDstWidth; nX++, nOutX++ )
    1615                 :            :                 {
    1616                 :          0 :                     const long  nMapX = pMapX[ nX ];
    1617                 :          0 :                     const sal_uLong nD = nVCLDitherLut[ nModY | ( nOutX & 0x0FL ) ];
    1618                 :            : 
    1619         [ #  # ]:          0 :                     aDstCol = lcl_AlphaBlend( nX, nY, nMapX, nMapY, pP, pA, pB, pAlphaW, nResAlpha );
    1620                 :            : 
    1621                 :          0 :                     aIndex.SetIndex( (sal_uInt8) ( nVCLRLut[ ( nVCLLut[ aDstCol.GetRed() ] + nD ) >> 16UL ] +
    1622                 :          0 :                                               nVCLGLut[ ( nVCLLut[ aDstCol.GetGreen() ] + nD ) >> 16UL ] +
    1623                 :          0 :                                               nVCLBLut[ ( nVCLLut[ aDstCol.GetBlue() ] + nD ) >> 16UL ] ) );
    1624         [ #  # ]:          0 :                     pW->SetPixel( nY, nX, aIndex );
    1625                 :            : 
    1626                 :          0 :                     aIndex.SetIndex( (sal_uInt8) ( nVCLRLut[ ( nVCLLut[ 255-nResAlpha ] + nD ) >> 16UL ] +
    1627                 :          0 :                                                    nVCLGLut[ ( nVCLLut[ 255-nResAlpha ] + nD ) >> 16UL ] +
    1628                 :          0 :                                                    nVCLBLut[ ( nVCLLut[ 255-nResAlpha ] + nD ) >> 16UL ] ) );
    1629         [ #  # ]:          0 :                     pAlphaW->SetPixel( nY, nX, aIndex );
    1630                 :            :                 }
    1631                 :            :             }
    1632                 :            :         }
    1633                 :            : 
    1634         [ #  # ]:          0 :         aBmp.ReleaseAccess( pB );
    1635         [ #  # ]:          0 :         aDither.ReleaseAccess( pW );
    1636 [ #  # ][ #  # ]:          0 :         res = aDither;
    1637                 :            :     }
    1638                 :            :     else
    1639                 :            :     {
    1640         [ +  - ]:         86 :         BitmapWriteAccess*  pB = aBmp.AcquireWriteAccess();
    1641 [ +  - ][ +  - ]:         86 :         if( pP && pA && pB )
                 [ +  - ]
    1642                 :            :         {
    1643         [ +  + ]:       1895 :             for( nY = 0; nY < nDstHeight; nY++ )
    1644                 :            :             {
    1645                 :       1809 :                 const long  nMapY = pMapY[ nY ];
    1646                 :            : 
    1647         [ +  + ]:      38856 :                 for( nX = 0; nX < nDstWidth; nX++ )
    1648                 :            :                 {
    1649                 :      37047 :                     const long nMapX = pMapX[ nX ];
    1650         [ +  - ]:      37047 :                     aDstCol = lcl_AlphaBlend( nX, nY, nMapX, nMapY, pP, pA, pB, pAlphaW, nResAlpha );
    1651                 :            : 
    1652         [ +  - ]:      37047 :                     pB->SetPixel( nY, nX, aDstCol );
    1653         [ +  - ]:      37047 :                     pAlphaW->SetPixel( nY, nX, Color(255L-nResAlpha, 255L-nResAlpha, 255L-nResAlpha) );
    1654                 :            :                 }
    1655                 :            :             }
    1656                 :            :         }
    1657                 :            : 
    1658         [ +  - ]:         86 :         aBmp.ReleaseAccess( pB );
    1659         [ +  - ]:         86 :         res = aBmp;
    1660                 :            :     }
    1661                 :            : 
    1662         [ +  - ]:         86 :     aAlphaBitmap.ReleaseAccess( pAlphaW );
    1663         [ +  - ]:         86 :     mpAlphaVDev->DrawBitmap( aDstRect.TopLeft(), aAlphaBitmap );
    1664         [ +  - ]:         86 :     mpAlphaVDev->EnableMapMode( bOldMapMode );
    1665                 :            : 
    1666         [ +  - ]:         86 :     return res;
    1667                 :            : }
    1668                 :            : 
    1669                 :     175246 : Bitmap OutputDevice::ImplBlend( Bitmap              aBmp,
    1670                 :            :                                 BitmapReadAccess*   pP,
    1671                 :            :                                 BitmapReadAccess*   pA,
    1672                 :            :                                 const sal_Int32     nOffY,
    1673                 :            :                                 const sal_Int32     nDstHeight,
    1674                 :            :                                 const sal_Int32     nOffX,
    1675                 :            :                                 const sal_Int32     nDstWidth,
    1676                 :            :                                 const Rectangle&    aBmpRect,
    1677                 :            :                                 const Size&         aOutSz,
    1678                 :            :                                 const bool          bHMirr,
    1679                 :            :                                 const bool          bVMirr,
    1680                 :            :                                 const long*         pMapX,
    1681                 :            :                                 const long*         pMapY )
    1682                 :            : {
    1683                 :     175246 :     BitmapColor aDstCol;
    1684         [ +  - ]:     175246 :     Bitmap      res;
    1685                 :            :     int         nX, nY;
    1686                 :            : 
    1687 [ +  - ][ -  + ]:     175246 :     if( GetBitCount() <= 8 )
    1688                 :            :     {
    1689 [ #  # ][ #  # ]:          0 :         Bitmap              aDither( aBmp.GetSizePixel(), 8 );
    1690                 :          0 :         BitmapColor         aIndex( 0 );
    1691         [ #  # ]:          0 :         BitmapReadAccess*   pB = aBmp.AcquireReadAccess();
    1692         [ #  # ]:          0 :         BitmapWriteAccess*  pW = aDither.AcquireWriteAccess();
    1693                 :            : 
    1694 [ #  # ][ #  # ]:          0 :         if( pB && pP && pA && pW )
         [ #  # ][ #  # ]
    1695                 :            :         {
    1696                 :            :             int nOutY;
    1697                 :            : 
    1698         [ #  # ]:          0 :             for( nY = 0, nOutY = nOffY; nY < nDstHeight; nY++, nOutY++ )
    1699                 :            :             {
    1700                 :          0 :                 const long nMapY = pMapY[ nY ];
    1701                 :          0 :                 const long nModY = ( nOutY & 0x0FL ) << 4L;
    1702                 :            :                 int nOutX;
    1703                 :            : 
    1704         [ #  # ]:          0 :                 for( nX = 0, nOutX = nOffX; nX < nDstWidth; nX++, nOutX++ )
    1705                 :            :                 {
    1706                 :          0 :                     const long  nMapX = pMapX[ nX ];
    1707                 :          0 :                     const sal_uLong nD = nVCLDitherLut[ nModY | ( nOutX & 0x0FL ) ];
    1708                 :            : 
    1709         [ #  # ]:          0 :                     aDstCol = pB->GetColor( nY, nX );
    1710 [ #  # ][ #  # ]:          0 :                     aDstCol.Merge( pP->GetColor( nMapY, nMapX ), (sal_uInt8) pA->GetPixel( nMapY, nMapX ) );
    1711                 :          0 :                     aIndex.SetIndex( (sal_uInt8) ( nVCLRLut[ ( nVCLLut[ aDstCol.GetRed() ] + nD ) >> 16UL ] +
    1712                 :          0 :                                               nVCLGLut[ ( nVCLLut[ aDstCol.GetGreen() ] + nD ) >> 16UL ] +
    1713                 :          0 :                                               nVCLBLut[ ( nVCLLut[ aDstCol.GetBlue() ] + nD ) >> 16UL ] ) );
    1714         [ #  # ]:          0 :                     pW->SetPixel( nY, nX, aIndex );
    1715                 :            :                 }
    1716                 :            :             }
    1717                 :            :         }
    1718                 :            : 
    1719         [ #  # ]:          0 :         aBmp.ReleaseAccess( pB );
    1720         [ #  # ]:          0 :         aDither.ReleaseAccess( pW );
    1721 [ #  # ][ #  # ]:          0 :         res = aDither;
    1722                 :            :     }
    1723                 :            :     else
    1724                 :            :     {
    1725         [ +  - ]:     175246 :         BitmapWriteAccess*  pB = aBmp.AcquireWriteAccess();
    1726                 :            : 
    1727                 :     175246 :         bool bFastBlend = false;
    1728 [ +  - ][ +  - ]:     175246 :         if( pP && pA && pB )
                 [ +  - ]
    1729                 :            :         {
    1730                 :            :             SalTwoRect aTR;
    1731                 :     175246 :             aTR.mnSrcX      = aBmpRect.Left();
    1732                 :     175246 :             aTR.mnSrcY      = aBmpRect.Top();
    1733         [ +  - ]:     175246 :             aTR.mnSrcWidth  = aBmpRect.GetWidth();
    1734         [ +  - ]:     175246 :             aTR.mnSrcHeight = aBmpRect.GetHeight();
    1735                 :     175246 :             aTR.mnDestX     = nOffX;
    1736                 :     175246 :             aTR.mnDestY     = nOffY;
    1737                 :     175246 :             aTR.mnDestWidth = aOutSz.Width();
    1738                 :     175246 :             aTR.mnDestHeight= aOutSz.Height();
    1739                 :            : 
    1740 [ +  - ][ +  - ]:     175246 :             if( !bHMirr && !bVMirr )
    1741         [ +  - ]:     175246 :                 bFastBlend = ImplFastBitmapBlending( *pB,*pP,*pA, aTR );
    1742                 :            :         }
    1743                 :            : 
    1744 [ +  - ][ +  - ]:     175246 :         if( pP && pA && pB && !bFastBlend )
         [ +  - ][ +  + ]
    1745                 :            :         {
    1746   [ +  +  -  - ]:      73446 :             switch( pP->GetScanlineFormat() )
    1747                 :            :             {
    1748                 :            :                 case( BMP_FORMAT_8BIT_PAL ):
    1749                 :            :                     {
    1750         [ +  + ]:     597464 :                         for( nY = 0; nY < nDstHeight; nY++ )
    1751                 :            :                         {
    1752                 :     562318 :                             const long  nMapY = pMapY[ nY ];
    1753                 :     562318 :                             Scanline    pPScan = pP->GetScanline( nMapY );
    1754                 :     562318 :                             Scanline    pAScan = pA->GetScanline( nMapY );
    1755                 :            : 
    1756         [ +  + ]:    9559200 :                             for( nX = 0; nX < nDstWidth; nX++ )
    1757                 :            :                             {
    1758                 :    8996882 :                                 const long nMapX = pMapX[ nX ];
    1759         [ +  - ]:    8996882 :                                 aDstCol = pB->GetPixel( nY, nX );
    1760                 :    8996882 :                                 pB->SetPixel( nY, nX, aDstCol.Merge( pP->GetPaletteColor( pPScan[ nMapX ] ),
    1761         [ +  - ]:    8996882 :                                                                      pAScan[ nMapX ] ) );
    1762                 :            :                             }
    1763                 :            :                         }
    1764                 :            :                     }
    1765                 :      35146 :                     break;
    1766                 :            : 
    1767                 :            :                 case( BMP_FORMAT_24BIT_TC_BGR ):
    1768                 :            :                     {
    1769         [ +  + ]:    1206069 :                         for( nY = 0; nY < nDstHeight; nY++ )
    1770                 :            :                         {
    1771                 :    1167769 :                             const long  nMapY = pMapY[ nY ];
    1772                 :    1167769 :                             Scanline    pPScan = pP->GetScanline( nMapY );
    1773                 :    1167769 :                             Scanline    pAScan = pA->GetScanline( nMapY );
    1774                 :            : 
    1775         [ +  + ]:  120095716 :                             for( nX = 0; nX < nDstWidth; nX++ )
    1776                 :            :                             {
    1777                 :  118927947 :                                 const long  nMapX = pMapX[ nX ];
    1778                 :  118927947 :                                 Scanline    pTmp = pPScan + nMapX * 3;
    1779                 :            : 
    1780         [ +  - ]:  118927947 :                                 aDstCol = pB->GetPixel( nY, nX );
    1781                 :  356783841 :                                 pB->SetPixel( nY, nX, aDstCol.Merge( pTmp[ 2 ], pTmp[ 1 ], pTmp[ 0 ],
    1782         [ +  - ]:  118927947 :                                                                      pAScan[ nMapX ] ) );
    1783                 :            :                             }
    1784                 :            :                         }
    1785                 :            :                     }
    1786                 :      38300 :                     break;
    1787                 :            : 
    1788                 :            :                 case( BMP_FORMAT_24BIT_TC_RGB ):
    1789                 :            :                     {
    1790         [ #  # ]:          0 :                         for( nY = 0; nY < nDstHeight; nY++ )
    1791                 :            :                         {
    1792                 :          0 :                             const long  nMapY = pMapY[ nY ];
    1793                 :          0 :                             Scanline    pPScan = pP->GetScanline( nMapY );
    1794                 :          0 :                             Scanline    pAScan = pA->GetScanline( nMapY );
    1795                 :            : 
    1796         [ #  # ]:          0 :                             for( nX = 0; nX < nDstWidth; nX++ )
    1797                 :            :                             {
    1798                 :          0 :                                 const long  nMapX = pMapX[ nX ];
    1799                 :          0 :                                 Scanline    pTmp = pPScan + nMapX * 3;
    1800                 :            : 
    1801         [ #  # ]:          0 :                                 aDstCol = pB->GetPixel( nY, nX );
    1802                 :          0 :                                 pB->SetPixel( nY, nX, aDstCol.Merge( pTmp[ 0 ], pTmp[ 1 ], pTmp[ 2 ],
    1803         [ #  # ]:          0 :                                                                      pAScan[ nMapX ] ) );
    1804                 :            :                             }
    1805                 :            :                         }
    1806                 :            :                     }
    1807                 :          0 :                     break;
    1808                 :            : 
    1809                 :            :                 default:
    1810                 :            :                 {
    1811         [ #  # ]:          0 :                     for( nY = 0; nY < nDstHeight; nY++ )
    1812                 :            :                     {
    1813                 :          0 :                         const long  nMapY = pMapY[ nY ];
    1814                 :          0 :                         Scanline    pAScan = pA->GetScanline( nMapY );
    1815                 :            : 
    1816         [ #  # ]:          0 :                         for( nX = 0; nX < nDstWidth; nX++ )
    1817                 :            :                         {
    1818                 :          0 :                             const long nMapX = pMapX[ nX ];
    1819         [ #  # ]:          0 :                             aDstCol = pB->GetPixel( nY, nX );
    1820                 :            :                             pB->SetPixel( nY, nX, aDstCol.Merge( pP->GetColor( nMapY, nMapX ),
    1821 [ #  # ][ #  # ]:          0 :                                                                  pAScan[ nMapX ] ) );
    1822                 :            :                         }
    1823                 :            :                     }
    1824                 :            :                 }
    1825                 :      73446 :                 break;
    1826                 :            :             }
    1827                 :            :         }
    1828                 :            : 
    1829         [ +  - ]:     175246 :         aBmp.ReleaseAccess( pB );
    1830         [ +  - ]:     175246 :         res = aBmp;
    1831                 :            :     }
    1832                 :            : 
    1833                 :     175246 :     return res;
    1834                 :            : }
    1835                 :            : 
    1836                 :     248082 : void OutputDevice::ImplDrawAlpha( const Bitmap& rBmp, const AlphaMask& rAlpha,
    1837                 :            :                                   const Point& rDestPt, const Size& rDestSize,
    1838                 :            :                                   const Point& rSrcPtPixel, const Size& rSrcSizePixel )
    1839                 :            : {
    1840                 :     248082 :     const Point aNullPt;
    1841         [ +  - ]:     248082 :     Point       aOutPt( LogicToPixel( rDestPt ) );
    1842         [ +  - ]:     248082 :     Size        aOutSz( LogicToPixel( rDestSize ) );
    1843         [ +  - ]:     248082 :     Rectangle   aDstRect( aNullPt, GetOutputSizePixel() );
    1844                 :     248082 :     const bool  bHMirr = aOutSz.Width() < 0;
    1845                 :     248082 :     const bool  bVMirr = aOutSz.Height() < 0;
    1846                 :            : 
    1847         [ +  + ]:     248082 :     if( OUTDEV_WINDOW == meOutDevType )
    1848                 :            :     {
    1849         [ +  - ]:     112766 :         const Region aPaintRgn( ( (Window*) this )->GetPaintRegion() );
    1850                 :            : 
    1851 [ +  - ][ +  + ]:     112766 :         if( !aPaintRgn.IsNull() )
    1852 [ +  - ][ +  - ]:     112766 :             aDstRect.Intersection( LogicToPixel( aPaintRgn.GetBoundRect() ) );
         [ +  - ][ +  - ]
    1853                 :            :     }
    1854                 :            : 
    1855         [ -  + ]:     248082 :     if( bHMirr )
    1856                 :            :     {
    1857                 :          0 :         aOutSz.Width() = -aOutSz.Width();
    1858                 :          0 :         aOutPt.X() -= ( aOutSz.Width() - 1L );
    1859                 :            :     }
    1860                 :            : 
    1861         [ -  + ]:     248082 :     if( bVMirr )
    1862                 :            :     {
    1863                 :          0 :         aOutSz.Height() = -aOutSz.Height();
    1864                 :          0 :         aOutPt.Y() -= ( aOutSz.Height() - 1L );
    1865                 :            :     }
    1866                 :            : 
    1867 [ +  - ][ +  - ]:     248082 :     if( !aDstRect.Intersection( Rectangle( aOutPt, aOutSz ) ).IsEmpty() )
         [ +  - ][ +  + ]
    1868                 :            :     {
    1869                 :     175606 :         bool bNativeAlpha = false;
    1870 [ +  + ][ +  - ]:     175606 :         static const char* pDisableNative = getenv( "SAL_DISABLE_NATIVE_ALPHA");
    1871                 :            :         // #i83087# Naturally, system alpha blending cannot work with
    1872                 :            :         // separate alpha VDev
    1873 [ +  + ][ +  - ]:     175606 :         if( !mpAlphaVDev && !pDisableNative && !bHMirr && !bVMirr )
         [ +  - ][ +  - ]
    1874                 :            :         {
    1875                 :     175520 :             Point aRelPt = aOutPt + Point( mnOutOffX, mnOutOffY );
    1876                 :            :             SalTwoRect aTR = {
    1877                 :     175520 :                 rSrcPtPixel.X(), rSrcPtPixel.Y(),
    1878                 :     175520 :                 rSrcSizePixel.Width(), rSrcSizePixel.Height(),
    1879                 :     175520 :                 aRelPt.X(), aRelPt.Y(),
    1880                 :     175520 :                 aOutSz.Width(), aOutSz.Height()
    1881                 :    1404160 :             };
    1882         [ +  - ]:     175520 :             SalBitmap* pSalSrcBmp = rBmp.ImplGetImpBitmap()->ImplGetSalBitmap();
    1883         [ +  - ]:     175520 :             SalBitmap* pSalAlphaBmp = rAlpha.ImplGetImpBitmap()->ImplGetSalBitmap();
    1884         [ +  - ]:     175520 :             bNativeAlpha = mpGraphics->DrawAlphaBitmap( aTR, *pSalSrcBmp, *pSalAlphaBmp, this );
    1885                 :            :         }
    1886                 :            : 
    1887                 :     175606 :         VirtualDevice* pOldVDev = mpAlphaVDev;
    1888                 :            : 
    1889 [ +  - ][ +  - ]:     175606 :         Rectangle aBmpRect( aNullPt, rBmp.GetSizePixel() );
    1890 [ +  - ][ +  - ]:     526818 :         if( !bNativeAlpha
                 [ +  - ]
    1891 [ +  - ][ +  - ]:     351212 :                 &&  !aBmpRect.Intersection( Rectangle( rSrcPtPixel, rSrcSizePixel ) ).IsEmpty() )
         [ +  - ][ +  - ]
                 [ #  # ]
    1892                 :            :         {
    1893                 :     175606 :             GDIMetaFile*    pOldMetaFile = mpMetaFile;
    1894                 :     175606 :             const bool      bOldMap = mbMap;
    1895 [ +  - ][ +  - ]:     175606 :             Bitmap          aBmp( GetBitmap( aDstRect.TopLeft(), aDstRect.GetSize() ) );
    1896                 :     175606 :             mpMetaFile = NULL;
    1897                 :     175606 :             mbMap = false;
    1898                 :            : 
    1899                 :            :             // #109044# The generated bitmap need not necessarily be
    1900                 :            :             // of aDstRect dimensions, it's internally clipped to
    1901                 :            :             // window bounds. Thus, we correct the dest size here,
    1902                 :            :             // since we later use it (in nDstWidth/Height) for pixel
    1903                 :            :             // access)
    1904                 :            :             // #i38887# reading from screen may sometimes fail
    1905 [ +  - ][ +  + ]:     175606 :             if( aBmp.ImplGetImpBitmap() )
    1906 [ +  - ][ +  - ]:     175332 :                 aDstRect.SetSize( aBmp.GetSizePixel() );
    1907                 :            : 
    1908                 :     175606 :             BitmapColor     aDstCol;
    1909 [ +  - ][ +  - ]:     175606 :             const long      nSrcWidth = aBmpRect.GetWidth(), nSrcHeight = aBmpRect.GetHeight();
    1910 [ +  - ][ +  - ]:     175606 :             const long      nDstWidth = aDstRect.GetWidth(), nDstHeight = aDstRect.GetHeight();
    1911                 :     175606 :             const long      nOutWidth = aOutSz.Width(), nOutHeight = aOutSz.Height();
    1912                 :            :             // calculate offset in original bitmap
    1913                 :            :             // in RTL case this is a little more complicated since the contents of the
    1914                 :            :             // bitmap is not mirrored (it never is), however the paint region and bmp region
    1915                 :            :             // are in mirrored coordinates, so the intersection of (aOutPt,aOutSz) with these
    1916                 :            :             // is content wise somewhere else and needs to take mirroring into account
    1917                 :     175606 :             const long      nOffX = IsRTLEnabled()
    1918         [ +  - ]:         32 :                                     ? aOutSz.Width() - aDstRect.GetWidth() - (aDstRect.Left() - aOutPt.X())
    1919         [ +  + ]:     175638 :                                     : aDstRect.Left() - aOutPt.X(),
    1920                 :     175606 :                             nOffY = aDstRect.Top() - aOutPt.Y();
    1921                 :            :             long            nX, nOutX, nY, nOutY;
    1922                 :     175606 :             long            nMirrOffX = 0;
    1923                 :     175606 :             long            nMirrOffY = 0;
    1924         [ +  - ]:     175606 :             long*           pMapX = new long[ nDstWidth ];
    1925         [ +  - ]:     175606 :             long*           pMapY = new long[ nDstHeight ];
    1926                 :            : 
    1927                 :            :             // create horizontal mapping table
    1928         [ -  + ]:     175606 :             if( bHMirr )
    1929                 :          0 :                 nMirrOffX = ( aBmpRect.Left() << 1 ) + nSrcWidth - 1;
    1930                 :            : 
    1931         [ +  + ]:    4850508 :             for( nX = 0L, nOutX = nOffX; nX < nDstWidth; nX++, nOutX++ )
    1932                 :            :             {
    1933                 :    4674902 :                 pMapX[ nX ] = aBmpRect.Left() + nOutX * nSrcWidth / nOutWidth;
    1934         [ -  + ]:    4674902 :                 if( bHMirr )
    1935                 :          0 :                     pMapX[ nX ] = nMirrOffX - pMapX[ nX ];
    1936                 :            :             }
    1937                 :            : 
    1938                 :            :             // create vertical mapping table
    1939         [ -  + ]:     175606 :             if( bVMirr )
    1940                 :          0 :                 nMirrOffY = ( aBmpRect.Top() << 1 ) + nSrcHeight - 1;
    1941                 :            : 
    1942         [ +  + ]:    4370860 :             for( nY = 0L, nOutY = nOffY; nY < nDstHeight; nY++, nOutY++ )
    1943                 :            :             {
    1944                 :    4195254 :                 pMapY[ nY ] = aBmpRect.Top() + nOutY * nSrcHeight / nOutHeight;
    1945                 :            : 
    1946         [ -  + ]:    4195254 :                 if( bVMirr )
    1947                 :          0 :                     pMapY[ nY ] = nMirrOffY - pMapY[ nY ];
    1948                 :            :             }
    1949                 :            : 
    1950         [ +  - ]:     175606 :             BitmapReadAccess*   pP = ( (Bitmap&) rBmp ).AcquireReadAccess();
    1951         [ +  - ]:     175606 :             BitmapReadAccess*   pA = ( (AlphaMask&) rAlpha ).AcquireReadAccess();
    1952                 :            : 
    1953                 :            :             DBG_ASSERT( pA->GetScanlineFormat() == BMP_FORMAT_8BIT_PAL ||
    1954                 :            :                         pA->GetScanlineFormat() == BMP_FORMAT_8BIT_TC_MASK,
    1955                 :            :                         "OutputDevice::ImplDrawAlpha(): non-8bit alpha no longer supported!" );
    1956                 :            : 
    1957                 :            :             // #i38887# reading from screen may sometimes fail
    1958 [ +  - ][ +  + ]:     175606 :             if( aBmp.ImplGetImpBitmap() )
    1959                 :            :             {
    1960         [ +  - ]:     175332 :                 Bitmap aTmp;
    1961                 :            : 
    1962         [ +  + ]:     175332 :                 if( mpAlphaVDev )
    1963                 :            :                 {
    1964                 :            :                     aTmp = ImplBlendWithAlpha(
    1965                 :            :                         aBmp,pP,pA,
    1966                 :            :                         aDstRect,
    1967                 :            :                         nOffY,nDstHeight,
    1968                 :            :                         nOffX,nDstWidth,
    1969 [ +  - ][ +  - ]:         86 :                         pMapX,pMapY );
         [ +  - ][ +  - ]
                 [ +  - ]
    1970                 :            :                 }
    1971                 :            :                 else
    1972                 :            :                 {
    1973                 :            :                     aTmp = ImplBlend(
    1974                 :            :                         aBmp,pP,pA,
    1975                 :            :                         nOffY,nDstHeight,
    1976                 :            :                         nOffX,nDstWidth,
    1977                 :            :                         aBmpRect,aOutSz,
    1978                 :            :                         bHMirr,bVMirr,
    1979 [ +  - ][ +  - ]:     175246 :                         pMapX,pMapY );
         [ +  - ][ +  - ]
                 [ +  - ]
    1980                 :            :                 }
    1981                 :            : 
    1982                 :            :                 // #110958# Disable alpha VDev, we're doing the necessary
    1983                 :            :                 // stuff explicitly furher below
    1984         [ +  + ]:     175332 :                 if( mpAlphaVDev )
    1985                 :         86 :                     mpAlphaVDev = NULL;
    1986                 :            : 
    1987                 :            :                 DrawBitmap( aDstRect.TopLeft(),
    1988         [ +  - ]:     175332 :                             aTmp );
    1989                 :            : 
    1990                 :            :                 // #110958# Enable alpha VDev again
    1991         [ +  - ]:     175332 :                 mpAlphaVDev = pOldVDev;
    1992                 :            :             }
    1993                 :            : 
    1994         [ +  - ]:     175606 :             ( (Bitmap&) rBmp ).ReleaseAccess( pP );
    1995         [ +  - ]:     175606 :             ( (AlphaMask&) rAlpha ).ReleaseAccess( pA );
    1996                 :            : 
    1997         [ +  - ]:     175606 :             delete[] pMapX;
    1998         [ +  - ]:     175606 :             delete[] pMapY;
    1999                 :     175606 :             mbMap = bOldMap;
    2000         [ +  - ]:     175606 :             mpMetaFile = pOldMetaFile;
    2001                 :            :         }
    2002                 :            :     }
    2003                 :     248082 : }
    2004                 :            : 
    2005                 :          0 : void OutputDevice::ImplPrintTransparent( const Bitmap& rBmp, const Bitmap& rMask,
    2006                 :            :                                          const Point& rDestPt, const Size& rDestSize,
    2007                 :            :                                          const Point& rSrcPtPixel, const Size& rSrcSizePixel )
    2008                 :            : {
    2009                 :          0 :     Point       aPt;
    2010         [ #  # ]:          0 :     Point       aDestPt( LogicToPixel( rDestPt ) );
    2011         [ #  # ]:          0 :     Size        aDestSz( LogicToPixel( rDestSize ) );
    2012         [ #  # ]:          0 :     Rectangle   aSrcRect( rSrcPtPixel, rSrcSizePixel );
    2013                 :            : 
    2014         [ #  # ]:          0 :     aSrcRect.Justify();
    2015                 :            : 
    2016 [ #  # ][ #  # ]:          0 :     if( !rBmp.IsEmpty() && aSrcRect.GetWidth() && aSrcRect.GetHeight() && aDestSz.Width() && aDestSz.Height() )
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    2017                 :            :     {
    2018 [ #  # ][ #  # ]:          0 :         Bitmap  aPaint( rBmp ), aMask( rMask );
    2019                 :          0 :         sal_uLong   nMirrFlags = 0UL;
    2020                 :            : 
    2021 [ #  # ][ #  # ]:          0 :         if( aMask.GetBitCount() > 1 )
    2022         [ #  # ]:          0 :             aMask.Convert( BMP_CONVERSION_1BIT_THRESHOLD );
    2023                 :            : 
    2024                 :            :         // mirrored horizontically
    2025         [ #  # ]:          0 :         if( aDestSz.Width() < 0L )
    2026                 :            :         {
    2027                 :          0 :             aDestSz.Width() = -aDestSz.Width();
    2028                 :          0 :             aDestPt.X() -= ( aDestSz.Width() - 1L );
    2029                 :          0 :             nMirrFlags |= BMP_MIRROR_HORZ;
    2030                 :            :         }
    2031                 :            : 
    2032                 :            :         // mirrored vertically
    2033         [ #  # ]:          0 :         if( aDestSz.Height() < 0L )
    2034                 :            :         {
    2035                 :          0 :             aDestSz.Height() = -aDestSz.Height();
    2036                 :          0 :             aDestPt.Y() -= ( aDestSz.Height() - 1L );
    2037                 :          0 :             nMirrFlags |= BMP_MIRROR_VERT;
    2038                 :            :         }
    2039                 :            : 
    2040                 :            :         // source cropped?
    2041 [ #  # ][ #  # ]:          0 :         if( aSrcRect != Rectangle( aPt, aPaint.GetSizePixel() ) )
         [ #  # ][ #  # ]
    2042                 :            :         {
    2043         [ #  # ]:          0 :             aPaint.Crop( aSrcRect );
    2044         [ #  # ]:          0 :             aMask.Crop( aSrcRect );
    2045                 :            :         }
    2046                 :            : 
    2047                 :            :         // destination mirrored
    2048         [ #  # ]:          0 :         if( nMirrFlags )
    2049                 :            :         {
    2050         [ #  # ]:          0 :             aPaint.Mirror( nMirrFlags );
    2051         [ #  # ]:          0 :             aMask.Mirror( nMirrFlags );
    2052                 :            :         }
    2053                 :            : 
    2054                 :            :         // we always want to have a mask
    2055         [ #  # ]:          0 :         if( aMask.IsEmpty() )
    2056                 :            :         {
    2057 [ #  # ][ #  # ]:          0 :             aMask = Bitmap( aSrcRect.GetSize(), 1 );
         [ #  # ][ #  # ]
    2058         [ #  # ]:          0 :             aMask.Erase( Color( COL_BLACK ) );
    2059                 :            :         }
    2060                 :            : 
    2061                 :            :         // do painting
    2062 [ #  # ][ #  # ]:          0 :         const long      nSrcWidth = aSrcRect.GetWidth(), nSrcHeight = aSrcRect.GetHeight();
    2063                 :            :         long            nX, nY, nWorkX, nWorkY, nWorkWidth, nWorkHeight;
    2064         [ #  # ]:          0 :         long*           pMapX = new long[ nSrcWidth + 1 ];
    2065         [ #  # ]:          0 :         long*           pMapY = new long[ nSrcHeight + 1 ];
    2066                 :          0 :         const bool      bOldMap = mbMap;
    2067                 :            : 
    2068                 :          0 :         mbMap = false;
    2069                 :            : 
    2070                 :            :         // create forward mapping tables
    2071         [ #  # ]:          0 :         for( nX = 0L; nX <= nSrcWidth; nX++ )
    2072                 :          0 :             pMapX[ nX ] = aDestPt.X() + FRound( (double) aDestSz.Width() * nX / nSrcWidth );
    2073                 :            : 
    2074         [ #  # ]:          0 :         for( nY = 0L; nY <= nSrcHeight; nY++ )
    2075                 :          0 :             pMapY[ nY ] = aDestPt.Y() + FRound( (double) aDestSz.Height() * nY / nSrcHeight );
    2076                 :            : 
    2077                 :            :         // walk through all rectangles of mask
    2078 [ #  # ][ #  # ]:          0 :         Region          aWorkRgn( aMask.CreateRegion( COL_BLACK, Rectangle( Point(), aMask.GetSizePixel() ) ) );
                 [ #  # ]
    2079                 :            :         ImplRegionInfo  aInfo;
    2080         [ #  # ]:          0 :         bool            bRgnRect = aWorkRgn.ImplGetFirstRect( aInfo, nWorkX, nWorkY, nWorkWidth, nWorkHeight );
    2081                 :            : 
    2082         [ #  # ]:          0 :         while( bRgnRect )
    2083                 :            :         {
    2084         [ #  # ]:          0 :             Bitmap          aBandBmp( aPaint );
    2085         [ #  # ]:          0 :             const Rectangle aBandRect( Point( nWorkX, nWorkY ), Size( nWorkWidth, nWorkHeight ) );
    2086                 :          0 :             const Point     aMapPt( pMapX[ nWorkX ], pMapY[ nWorkY ] );
    2087                 :          0 :             const Size      aMapSz( pMapX[ nWorkX + nWorkWidth ] - aMapPt.X(), pMapY[ nWorkY + nWorkHeight ] - aMapPt.Y() );
    2088                 :            : 
    2089         [ #  # ]:          0 :             aBandBmp.Crop( aBandRect );
    2090 [ #  # ][ #  # ]:          0 :             ImplDrawBitmap( aMapPt, aMapSz, Point(), aBandBmp.GetSizePixel(), aBandBmp, META_BMPSCALEPART_ACTION );
    2091         [ #  # ]:          0 :             bRgnRect = aWorkRgn.ImplGetNextRect( aInfo, nWorkX, nWorkY, nWorkWidth, nWorkHeight );
    2092         [ #  # ]:          0 :         }
    2093                 :            : 
    2094                 :          0 :         mbMap = bOldMap;
    2095                 :            : 
    2096         [ #  # ]:          0 :         delete[] pMapX;
    2097 [ #  # ][ #  # ]:          0 :         delete[] pMapY;
         [ #  # ][ #  # ]
    2098                 :            :     }
    2099                 :          0 : }
    2100                 :            : 
    2101                 :          0 : void OutputDevice::ImplPrintMask( const Bitmap& rMask, const Color& rMaskColor,
    2102                 :            :                                   const Point& rDestPt, const Size& rDestSize,
    2103                 :            :                                   const Point& rSrcPtPixel, const Size& rSrcSizePixel )
    2104                 :            : {
    2105                 :          0 :     Point       aPt;
    2106         [ #  # ]:          0 :     Point       aDestPt( LogicToPixel( rDestPt ) );
    2107         [ #  # ]:          0 :     Size        aDestSz( LogicToPixel( rDestSize ) );
    2108         [ #  # ]:          0 :     Rectangle   aSrcRect( rSrcPtPixel, rSrcSizePixel );
    2109                 :            : 
    2110         [ #  # ]:          0 :     aSrcRect.Justify();
    2111                 :            : 
    2112 [ #  # ][ #  # ]:          0 :     if( !rMask.IsEmpty() && aSrcRect.GetWidth() && aSrcRect.GetHeight() && aDestSz.Width() && aDestSz.Height() )
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    2113                 :            :     {
    2114         [ #  # ]:          0 :         Bitmap  aMask( rMask );
    2115                 :          0 :         sal_uLong   nMirrFlags = 0UL;
    2116                 :            : 
    2117 [ #  # ][ #  # ]:          0 :         if( aMask.GetBitCount() > 1 )
    2118         [ #  # ]:          0 :             aMask.Convert( BMP_CONVERSION_1BIT_THRESHOLD );
    2119                 :            : 
    2120                 :            :         // mirrored horizontically
    2121         [ #  # ]:          0 :         if( aDestSz.Width() < 0L )
    2122                 :            :         {
    2123                 :          0 :             aDestSz.Width() = -aDestSz.Width();
    2124                 :          0 :             aDestPt.X() -= ( aDestSz.Width() - 1L );
    2125                 :          0 :             nMirrFlags |= BMP_MIRROR_HORZ;
    2126                 :            :         }
    2127                 :            : 
    2128                 :            :         // mirrored vertically
    2129         [ #  # ]:          0 :         if( aDestSz.Height() < 0L )
    2130                 :            :         {
    2131                 :          0 :             aDestSz.Height() = -aDestSz.Height();
    2132                 :          0 :             aDestPt.Y() -= ( aDestSz.Height() - 1L );
    2133                 :          0 :             nMirrFlags |= BMP_MIRROR_VERT;
    2134                 :            :         }
    2135                 :            : 
    2136                 :            :         // source cropped?
    2137 [ #  # ][ #  # ]:          0 :         if( aSrcRect != Rectangle( aPt, aMask.GetSizePixel() ) )
         [ #  # ][ #  # ]
    2138         [ #  # ]:          0 :             aMask.Crop( aSrcRect );
    2139                 :            : 
    2140                 :            :         // destination mirrored
    2141         [ #  # ]:          0 :         if( nMirrFlags )
    2142         [ #  # ]:          0 :             aMask.Mirror( nMirrFlags );
    2143                 :            : 
    2144                 :            :         // do painting
    2145 [ #  # ][ #  # ]:          0 :         const long      nSrcWidth = aSrcRect.GetWidth(), nSrcHeight = aSrcRect.GetHeight();
    2146                 :            :         long            nX, nY, nWorkX, nWorkY, nWorkWidth, nWorkHeight;
    2147         [ #  # ]:          0 :         long*           pMapX = new long[ nSrcWidth + 1 ];
    2148         [ #  # ]:          0 :         long*           pMapY = new long[ nSrcHeight + 1 ];
    2149                 :          0 :         GDIMetaFile*    pOldMetaFile = mpMetaFile;
    2150                 :          0 :         const bool      bOldMap = mbMap;
    2151                 :            : 
    2152                 :          0 :         mpMetaFile = NULL;
    2153                 :          0 :         mbMap = false;
    2154         [ #  # ]:          0 :         Push( PUSH_FILLCOLOR | PUSH_LINECOLOR );
    2155         [ #  # ]:          0 :         SetLineColor( rMaskColor );
    2156         [ #  # ]:          0 :         SetFillColor( rMaskColor );
    2157         [ #  # ]:          0 :         ImplInitLineColor();
    2158         [ #  # ]:          0 :         ImplInitFillColor();
    2159                 :            : 
    2160                 :            :         // create forward mapping tables
    2161         [ #  # ]:          0 :         for( nX = 0L; nX <= nSrcWidth; nX++ )
    2162                 :          0 :             pMapX[ nX ] = aDestPt.X() + FRound( (double) aDestSz.Width() * nX / nSrcWidth );
    2163                 :            : 
    2164         [ #  # ]:          0 :         for( nY = 0L; nY <= nSrcHeight; nY++ )
    2165                 :          0 :             pMapY[ nY ] = aDestPt.Y() + FRound( (double) aDestSz.Height() * nY / nSrcHeight );
    2166                 :            : 
    2167                 :            :         // walk through all rectangles of mask
    2168 [ #  # ][ #  # ]:          0 :         Region          aWorkRgn( aMask.CreateRegion( COL_BLACK, Rectangle( Point(), aMask.GetSizePixel() ) ) );
                 [ #  # ]
    2169                 :            :         ImplRegionInfo  aInfo;
    2170         [ #  # ]:          0 :         bool            bRgnRect = aWorkRgn.ImplGetFirstRect( aInfo, nWorkX, nWorkY, nWorkWidth, nWorkHeight );
    2171                 :            : 
    2172         [ #  # ]:          0 :         while( bRgnRect )
    2173                 :            :         {
    2174                 :          0 :             const Point aMapPt( pMapX[ nWorkX ], pMapY[ nWorkY ] );
    2175                 :          0 :             const Size  aMapSz( pMapX[ nWorkX + nWorkWidth ] - aMapPt.X(), pMapY[ nWorkY + nWorkHeight ] - aMapPt.Y() );
    2176                 :            : 
    2177 [ #  # ][ #  # ]:          0 :             DrawRect( Rectangle( aMapPt, aMapSz ) );
    2178         [ #  # ]:          0 :             bRgnRect = aWorkRgn.ImplGetNextRect( aInfo, nWorkX, nWorkY, nWorkWidth, nWorkHeight );
    2179                 :            :         }
    2180                 :            : 
    2181         [ #  # ]:          0 :         Pop();
    2182         [ #  # ]:          0 :         delete[] pMapX;
    2183         [ #  # ]:          0 :         delete[] pMapY;
    2184                 :          0 :         mbMap = bOldMap;
    2185 [ #  # ][ #  # ]:          0 :         mpMetaFile = pOldMetaFile;
    2186                 :            :     }
    2187                 :          0 : }
    2188                 :            : 
    2189                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10