LCOV - code coverage report
Current view: top level - libreoffice/vcl/source/gdi - outdev2.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 326 953 34.2 %
Date: 2012-12-27 Functions: 17 37 45.9 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10