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

Generated by: LCOV version 1.10