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

Generated by: LCOV version 1.10