LCOV - code coverage report
Current view: top level - libreoffice/vcl/source/gdi - outdev6.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 72 615 11.7 %
Date: 2012-12-27 Functions: 6 11 54.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/outdev.hxx>
      22             : #include <vcl/virdev.hxx>
      23             : #include <vcl/bmpacc.hxx>
      24             : #include <vcl/metaact.hxx>
      25             : #include <vcl/gdimtf.hxx>
      26             : #include <vcl/svapp.hxx>
      27             : #include <vcl/wrkwin.hxx>
      28             : #include <vcl/graph.hxx>
      29             : 
      30             : #include <wall2.hxx>
      31             : #include <salgdi.hxx>
      32             : #include <window.h>
      33             : #include <svdata.hxx>
      34             : #include <outdev.h>
      35             : 
      36             : #include <com/sun/star/uno/Sequence.hxx>
      37             : 
      38             : #include <basegfx/vector/b2dvector.hxx>
      39             : #include <basegfx/polygon/b2dpolypolygon.hxx>
      40             : #include <basegfx/polygon/b2dpolygon.hxx>
      41             : #include <basegfx/matrix/b2dhommatrix.hxx>
      42             : 
      43             : #include <math.h>
      44             : 
      45             : // ========================================================================
      46             : 
      47             : DBG_NAMEEX( OutputDevice )
      48             : 
      49             : // ------------------------------------------------------------------------
      50             : 
      51           0 : void OutputDevice::DrawGrid( const Rectangle& rRect, const Size& rDist, sal_uLong nFlags )
      52             : {
      53             :     OSL_TRACE( "OutputDevice::DrawGrid()" );
      54             :     DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
      55             : 
      56           0 :     Rectangle aDstRect( PixelToLogic( Point() ), GetOutputSize() );
      57           0 :     aDstRect.Intersection( rRect );
      58             : 
      59           0 :     if( aDstRect.IsEmpty() || ImplIsRecordLayout() )
      60             :         return;
      61             : 
      62           0 :     if( !mpGraphics && !ImplGetGraphics() )
      63             :         return;
      64             : 
      65           0 :     if( mbInitClipRegion )
      66           0 :         ImplInitClipRegion();
      67             : 
      68           0 :     if( mbOutputClipped )
      69             :         return;
      70             : 
      71           0 :     const long  nDistX = Max( rDist.Width(), 1L );
      72           0 :     const long  nDistY = Max( rDist.Height(), 1L );
      73           0 :     long        nX = ( rRect.Left() >= aDstRect.Left() ) ? rRect.Left() : ( rRect.Left() + ( ( aDstRect.Left() - rRect.Left() ) / nDistX ) * nDistX );
      74           0 :     long        nY = ( rRect.Top() >= aDstRect.Top() ) ? rRect.Top() : ( rRect.Top() + ( ( aDstRect.Top() - rRect.Top() ) / nDistY ) * nDistY );
      75           0 :     const long  nRight = aDstRect.Right();
      76           0 :     const long  nBottom = aDstRect.Bottom();
      77           0 :     const long  nStartX = ImplLogicXToDevicePixel( nX );
      78           0 :     const long  nEndX = ImplLogicXToDevicePixel( nRight );
      79           0 :     const long  nStartY = ImplLogicYToDevicePixel( nY );
      80           0 :     const long  nEndY = ImplLogicYToDevicePixel( nBottom );
      81           0 :     long        nHorzCount = 0L;
      82           0 :     long        nVertCount = 0L;
      83             : 
      84           0 :     ::com::sun::star::uno::Sequence< sal_Int32 > aVertBuf;
      85           0 :     ::com::sun::star::uno::Sequence< sal_Int32 > aHorzBuf;
      86             : 
      87           0 :     if( ( nFlags & GRID_DOTS ) || ( nFlags & GRID_HORZLINES ) )
      88             :     {
      89           0 :         aVertBuf.realloc( aDstRect.GetHeight() / nDistY + 2L );
      90           0 :         aVertBuf[ nVertCount++ ] = nStartY;
      91           0 :         while( ( nY += nDistY ) <= nBottom )
      92           0 :             aVertBuf[ nVertCount++ ] = ImplLogicYToDevicePixel( nY );
      93             :     }
      94             : 
      95           0 :     if( ( nFlags & GRID_DOTS ) || ( nFlags & GRID_VERTLINES ) )
      96             :     {
      97           0 :         aHorzBuf.realloc( aDstRect.GetWidth() / nDistX + 2L );
      98           0 :         aHorzBuf[ nHorzCount++ ] = nStartX;
      99           0 :         while( ( nX += nDistX ) <= nRight )
     100           0 :             aHorzBuf[ nHorzCount++ ] = ImplLogicXToDevicePixel( nX );
     101             :     }
     102             : 
     103           0 :     if( mbInitLineColor )
     104           0 :         ImplInitLineColor();
     105             : 
     106           0 :     if( mbInitFillColor )
     107           0 :         ImplInitFillColor();
     108             : 
     109           0 :     const sal_Bool bOldMap = mbMap;
     110           0 :     EnableMapMode( sal_False );
     111             : 
     112           0 :     if( nFlags & GRID_DOTS )
     113             :     {
     114           0 :         for( long i = 0L; i < nVertCount; i++ )
     115           0 :             for( long j = 0L, Y = aVertBuf[ i ]; j < nHorzCount; j++ )
     116           0 :                 mpGraphics->DrawPixel( aHorzBuf[ j ], Y, this );
     117             :     }
     118             :     else
     119             :     {
     120           0 :         if( nFlags & GRID_HORZLINES )
     121             :         {
     122           0 :             for( long i = 0L; i < nVertCount; i++ )
     123             :             {
     124           0 :                 nY = aVertBuf[ i ];
     125           0 :                 mpGraphics->DrawLine( nStartX, nY, nEndX, nY, this );
     126             :             }
     127             :         }
     128             : 
     129           0 :         if( nFlags & GRID_VERTLINES )
     130             :         {
     131           0 :             for( long i = 0L; i < nHorzCount; i++ )
     132             :             {
     133           0 :                 nX = aHorzBuf[ i ];
     134           0 :                 mpGraphics->DrawLine( nX, nStartY, nX, nEndY, this );
     135             :             }
     136             :         }
     137             :     }
     138             : 
     139           0 :     EnableMapMode( bOldMap );
     140             : 
     141           0 :     if( mpAlphaVDev )
     142           0 :         mpAlphaVDev->DrawGrid( rRect, rDist, nFlags );
     143             : }
     144             : 
     145             : // ------------------------------------------------------------------------
     146             : // Caution: This method is nearly the same as
     147             : // void OutputDevice::DrawPolyPolygon( const basegfx::B2DPolyPolygon& rB2DPolyPoly )
     148             : // so when changes are made here do not forget to make change sthere, too
     149             : 
     150           0 : void OutputDevice::DrawTransparent( const basegfx::B2DPolyPolygon& rB2DPolyPoly, double fTransparency)
     151             : {
     152             :     OSL_TRACE( "OutputDevice::DrawTransparent(B2D&,transparency)" );
     153             :     DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
     154             : 
     155             :     // AW: Do NOT paint empty PolyPolygons
     156           0 :     if(!rB2DPolyPoly.count())
     157             :         return;
     158             : 
     159             :     // we need a graphics
     160           0 :     if( !mpGraphics )
     161           0 :         if( !ImplGetGraphics() )
     162             :             return;
     163             : 
     164           0 :     if( mbInitClipRegion )
     165           0 :         ImplInitClipRegion();
     166           0 :     if( mbOutputClipped )
     167             :         return;
     168             : 
     169           0 :     if( mbInitLineColor )
     170           0 :         ImplInitLineColor();
     171           0 :     if( mbInitFillColor )
     172           0 :         ImplInitFillColor();
     173             : 
     174           0 :     if((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW)
     175           0 :         && mpGraphics->supportsOperation(OutDevSupport_B2DDraw)
     176           0 :         && ROP_OVERPAINT == GetRasterOp() )
     177             :     {
     178             :         // b2dpolygon support not implemented yet on non-UNX platforms
     179           0 :         const ::basegfx::B2DHomMatrix aTransform = ImplGetDeviceTransformation();
     180           0 :         basegfx::B2DPolyPolygon aB2DPolyPolygon(rB2DPolyPoly);
     181             : 
     182             :         // transform the polygon into device space and ensure it is closed
     183           0 :         aB2DPolyPolygon.transform( aTransform );
     184           0 :         aB2DPolyPolygon.setClosed( true );
     185             : 
     186           0 :         bool bDrawnOk = true;
     187           0 :         if( IsFillColor() )
     188           0 :             bDrawnOk = mpGraphics->DrawPolyPolygon( aB2DPolyPolygon, fTransparency, this );
     189           0 :         if( bDrawnOk && IsLineColor() )
     190             :         {
     191           0 :             const basegfx::B2DVector aHairlineWidth(1,1);
     192           0 :             const int nPolyCount = aB2DPolyPolygon.count();
     193           0 :             for( int nPolyIdx = 0; nPolyIdx < nPolyCount; ++nPolyIdx )
     194             :             {
     195           0 :                 const ::basegfx::B2DPolygon aOnePoly = aB2DPolyPolygon.getB2DPolygon( nPolyIdx );
     196           0 :                 mpGraphics->DrawPolyLine( aOnePoly, fTransparency, aHairlineWidth, ::basegfx::B2DLINEJOIN_NONE, com::sun::star::drawing::LineCap_BUTT, this );
     197           0 :             }
     198             :         }
     199             : 
     200           0 :         if( bDrawnOk )
     201             :         {
     202           0 :             if( mpMetaFile )
     203           0 :                 mpMetaFile->AddAction( new MetaTransparentAction( PolyPolygon( rB2DPolyPoly ), static_cast< sal_uInt16 >(fTransparency * 100.0)));
     204             :             return;
     205           0 :         }
     206             :     }
     207             : 
     208             :     // fallback to old polygon drawing if needed
     209           0 :     const PolyPolygon aToolsPolyPolygon( rB2DPolyPoly );
     210           0 :     DrawTransparent(PolyPolygon(rB2DPolyPoly), static_cast< sal_uInt16 >(fTransparency * 100.0));
     211             : }
     212             : 
     213             : // ------------------------------------------------------------------------
     214             : 
     215          10 : void OutputDevice::DrawTransparent( const PolyPolygon& rPolyPoly,
     216             :                                     sal_uInt16 nTransparencePercent )
     217             : {
     218             :     OSL_TRACE( "OutputDevice::DrawTransparent()" );
     219             :     DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
     220             : 
     221             :     // short circuit for drawing an opaque polygon
     222          10 :     if( (nTransparencePercent < 1) || ((mnDrawMode & DRAWMODE_NOTRANSPARENCY) != 0) )
     223             :     {
     224           0 :         DrawPolyPolygon( rPolyPoly );
     225           0 :         return;
     226             :     }
     227             : 
     228             :     // short circut for drawing an invisible polygon
     229          10 :     if( !mbFillColor || (nTransparencePercent >= 100) )
     230             :     {
     231             :         // short circuit if the polygon border is invisible too
     232          10 :         if( !mbLineColor )
     233          10 :             return;
     234             : 
     235             :         // DrawTransparent() assumes that the border is NOT to be drawn transparently???
     236           0 :         Push( PUSH_FILLCOLOR );
     237           0 :         SetFillColor();
     238           0 :         DrawPolyPolygon( rPolyPoly );
     239           0 :         Pop();
     240           0 :         return;
     241             :     }
     242             : 
     243             :     // handle metafile recording
     244           0 :     if( mpMetaFile )
     245           0 :         mpMetaFile->AddAction( new MetaTransparentAction( rPolyPoly, nTransparencePercent ) );
     246             : 
     247           0 :     bool bDrawn = !IsDeviceOutputNecessary() || ImplIsRecordLayout();
     248           0 :     if( bDrawn )
     249           0 :         return;
     250             : 
     251             :     // get the device graphics as drawing target
     252           0 :     if( !mpGraphics )
     253           0 :         if( !ImplGetGraphics() )
     254           0 :             return;
     255             : 
     256             :     // debug helper:
     257           0 :     static const char* pDisableNative = getenv( "SAL_DISABLE_NATIVE_ALPHA");
     258             : 
     259             :     // try hard to draw it directly, because the emulation layers are slower
     260           0 :     if( !pDisableNative
     261           0 :         && mpGraphics->supportsOperation( OutDevSupport_B2DDraw )
     262             : #if defined UNX && ! defined QUARTZ
     263           0 :             && GetBitCount() > 8
     264             : #endif
     265             : #ifdef WIN32
     266             :         // workaround bad dithering on remote displaying when using GDI+ with toolbar buttoin hilighting
     267             :         && !rPolyPoly.IsRect()
     268             : #endif
     269             :         )
     270             :     {
     271             :         // prepare the graphics device
     272           0 :         if( mbInitClipRegion )
     273           0 :             ImplInitClipRegion();
     274           0 :         if( mbOutputClipped )
     275             :             return;
     276           0 :         if( mbInitLineColor )
     277           0 :             ImplInitLineColor();
     278           0 :         if( mbInitFillColor )
     279           0 :             ImplInitFillColor();
     280             : 
     281             :         // get the polygon in device coordinates
     282           0 :         basegfx::B2DPolyPolygon aB2DPolyPolygon( rPolyPoly.getB2DPolyPolygon() );
     283           0 :         const ::basegfx::B2DHomMatrix aTransform = ImplGetDeviceTransformation();
     284           0 :         aB2DPolyPolygon.transform( aTransform );
     285             : 
     286           0 :         const double fTransparency = 0.01 * nTransparencePercent;
     287           0 :         if( mbFillColor )
     288             :         {
     289             :             // draw the transparent polygon
     290             :             // NOTE: filled polygons are assumed to be drawn as if they were always closed
     291           0 :             bDrawn = mpGraphics->DrawPolyPolygon( aB2DPolyPolygon, fTransparency, this );
     292             :         }
     293             : 
     294           0 :         if( mbLineColor )
     295             :         {
     296             :             // disable the fill color for now
     297           0 :             mpGraphics->SetFillColor();
     298             :             // draw the border line
     299           0 :             const basegfx::B2DVector aLineWidths( 1, 1 );
     300           0 :             const int nPolyCount = aB2DPolyPolygon.count();
     301           0 :             for( int nPolyIdx = 0; nPolyIdx < nPolyCount; ++nPolyIdx )
     302             :             {
     303           0 :                 const ::basegfx::B2DPolygon& rPolygon = aB2DPolyPolygon.getB2DPolygon( nPolyIdx );
     304           0 :                 bDrawn = mpGraphics->DrawPolyLine( rPolygon, fTransparency, aLineWidths, ::basegfx::B2DLINEJOIN_NONE, com::sun::star::drawing::LineCap_BUTT, this );
     305           0 :             }
     306             :             // prepare to restore the fill color
     307           0 :             mbInitFillColor = mbFillColor;
     308           0 :         }
     309             :     }
     310             : 
     311           0 :     if( bDrawn )
     312           0 :         return;
     313             : 
     314           0 :     VirtualDevice* pOldAlphaVDev = mpAlphaVDev;
     315             : 
     316             :     // #110958# Disable alpha VDev, we perform the necessary
     317             :     // operation explicitly further below.
     318           0 :     if( mpAlphaVDev )
     319           0 :         mpAlphaVDev = NULL;
     320             : 
     321           0 :     GDIMetaFile* pOldMetaFile = mpMetaFile;
     322           0 :     mpMetaFile = NULL;
     323             : 
     324           0 :     if( OUTDEV_PRINTER == meOutDevType )
     325             :     {
     326           0 :         if(100 <= nTransparencePercent)
     327             :         {
     328             :             // #i112959# 100% transparent, draw nothing
     329             :             return;
     330             :         }
     331             : 
     332           0 :         Rectangle       aPolyRect( LogicToPixel( rPolyPoly ).GetBoundRect() );
     333           0 :         const Size      aDPISize( LogicToPixel( Size( 1, 1 ), MAP_INCH ) );
     334           0 :         const long      nBaseExtent = Max( FRound( aDPISize.Width() / 300. ), 1L );
     335             :         long            nMove;
     336             :         const sal_uInt16    nTrans = ( nTransparencePercent < 13 ) ? 0 :
     337             :             ( nTransparencePercent < 38 ) ? 25 :
     338             :             ( nTransparencePercent < 63 ) ? 50 :
     339           0 :             ( nTransparencePercent < 88 ) ? 75 : 100;
     340             : 
     341           0 :         switch( nTrans )
     342             :         {
     343           0 :             case( 25 ): nMove = nBaseExtent * 3; break;
     344           0 :             case( 50 ): nMove = nBaseExtent * 4; break;
     345           0 :             case( 75 ): nMove = nBaseExtent * 6; break;
     346             : 
     347             :                 // #i112959#  very transparent (88 < nTransparencePercent <= 99)
     348           0 :             case( 100 ): nMove = nBaseExtent * 8; break;
     349             : 
     350             :                 // #i112959# not transparent (nTransparencePercent < 13)
     351           0 :             default:    nMove = 0; break;
     352             :         }
     353             : 
     354           0 :         Push( PUSH_CLIPREGION | PUSH_LINECOLOR );
     355           0 :         IntersectClipRegion( rPolyPoly );
     356           0 :         SetLineColor( GetFillColor() );
     357           0 :         const sal_Bool bOldMap = mbMap;
     358           0 :         EnableMapMode( sal_False );
     359             : 
     360           0 :         if(nMove)
     361             :         {
     362           0 :             Rectangle aRect( aPolyRect.TopLeft(), Size( aPolyRect.GetWidth(), nBaseExtent ) );
     363           0 :             while( aRect.Top() <= aPolyRect.Bottom() )
     364             :             {
     365           0 :                 DrawRect( aRect );
     366           0 :                 aRect.Move( 0, nMove );
     367             :             }
     368             : 
     369           0 :             aRect = Rectangle( aPolyRect.TopLeft(), Size( nBaseExtent, aPolyRect.GetHeight() ) );
     370           0 :             while( aRect.Left() <= aPolyRect.Right() )
     371             :             {
     372           0 :                 DrawRect( aRect );
     373           0 :                 aRect.Move( nMove, 0 );
     374             :             }
     375             :         }
     376             :         else
     377             :         {
     378             :             // #i112959# if not transparent, draw full rectangle in clip region
     379           0 :             DrawRect( aPolyRect );
     380             :         }
     381             : 
     382           0 :         EnableMapMode( bOldMap );
     383           0 :         Pop();
     384             :     }
     385             :     else
     386             :     {
     387           0 :         PolyPolygon    aPolyPoly( LogicToPixel( rPolyPoly ) );
     388           0 :         Rectangle       aPolyRect( aPolyPoly.GetBoundRect() );
     389           0 :         Point           aPoint;
     390           0 :         Rectangle       aDstRect( aPoint, GetOutputSizePixel() );
     391             : 
     392           0 :         aDstRect.Intersection( aPolyRect );
     393             : 
     394           0 :         if( OUTDEV_WINDOW == meOutDevType )
     395             :         {
     396           0 :             const Region aPaintRgn( ( (Window*) this )->GetPaintRegion() );
     397             : 
     398           0 :             if( !aPaintRgn.IsNull() )
     399           0 :                 aDstRect.Intersection( LogicToPixel( aPaintRgn ).GetBoundRect() );
     400             :         }
     401             : 
     402           0 :         if( !aDstRect.IsEmpty() )
     403             :         {
     404             :             // #i66849# Added fast path for exactly rectangular
     405             :             // polygons
     406             :             // #i83087# Naturally, system alpha blending cannot
     407             :             // work with separate alpha VDev
     408           0 :             if( !mpAlphaVDev && !pDisableNative && aPolyPoly.IsRect() )
     409             :             {
     410             :                 // setup Graphics only here (other cases delegate
     411             :                 // to basic OutDev methods)
     412           0 :                 if ( mbInitClipRegion )
     413           0 :                     ImplInitClipRegion();
     414           0 :                 if ( mbInitLineColor )
     415           0 :                     ImplInitLineColor();
     416           0 :                 if ( mbInitFillColor )
     417           0 :                     ImplInitFillColor();
     418             : 
     419           0 :                 Rectangle aLogicPolyRect( rPolyPoly.GetBoundRect() );
     420           0 :                 Rectangle aPixelRect( ImplLogicToDevicePixel( aLogicPolyRect ) );
     421             : 
     422           0 :                 if( !mbOutputClipped )
     423             :                 {
     424             :                     bDrawn = mpGraphics->DrawAlphaRect(
     425           0 :                         aPixelRect.Left(), aPixelRect.Top(),
     426             :                         // #i98405# use methods with small g, else one pixel too much will be painted.
     427             :                         // This is because the source is a polygon which when painted would not paint
     428             :                         // the rightmost and lowest pixel line(s), so use one pixel less for the
     429             :                         // rectangle, too.
     430             :                         aPixelRect.getWidth(), aPixelRect.getHeight(),
     431           0 :                         sal::static_int_cast<sal_uInt8>(nTransparencePercent),
     432           0 :                         this );
     433             :                 }
     434             :                 else
     435           0 :                     bDrawn = true;
     436             :             }
     437             : 
     438           0 :             if( !bDrawn )
     439             :             {
     440           0 :                 VirtualDevice   aVDev( *this, 1 );
     441           0 :                 const Size      aDstSz( aDstRect.GetSize() );
     442           0 :                 const sal_uInt8     cTrans = (sal_uInt8) MinMax( FRound( nTransparencePercent * 2.55 ), 0, 255 );
     443             : 
     444           0 :                 if( aDstRect.Left() || aDstRect.Top() )
     445           0 :                     aPolyPoly.Move( -aDstRect.Left(), -aDstRect.Top() );
     446             : 
     447           0 :                 if( aVDev.SetOutputSizePixel( aDstSz ) )
     448             :                 {
     449           0 :                     const sal_Bool bOldMap = mbMap;
     450             : 
     451           0 :                     EnableMapMode( sal_False );
     452             : 
     453           0 :                     aVDev.SetLineColor( COL_BLACK );
     454           0 :                     aVDev.SetFillColor( COL_BLACK );
     455           0 :                     aVDev.DrawPolyPolygon( aPolyPoly );
     456             : 
     457           0 :                     Bitmap              aPaint( GetBitmap( aDstRect.TopLeft(), aDstSz ) );
     458           0 :                     Bitmap              aPolyMask( aVDev.GetBitmap( Point(), aDstSz ) );
     459             : 
     460             :                     // #107766# check for non-empty bitmaps before accessing them
     461           0 :                     if( !!aPaint && !!aPolyMask )
     462             :                     {
     463           0 :                         BitmapWriteAccess*  pW = aPaint.AcquireWriteAccess();
     464           0 :                         BitmapReadAccess*   pR = aPolyMask.AcquireReadAccess();
     465             : 
     466           0 :                         if( pW && pR )
     467             :                         {
     468           0 :                             BitmapColor         aPixCol;
     469           0 :                             const BitmapColor   aFillCol( GetFillColor() );
     470           0 :                             const BitmapColor   aWhite( pR->GetBestMatchingColor( Color( COL_WHITE ) ) );
     471           0 :                             const BitmapColor   aBlack( pR->GetBestMatchingColor( Color( COL_BLACK ) ) );
     472           0 :                             const long          nWidth = pW->Width(), nHeight = pW->Height();
     473           0 :                             const long          nR = aFillCol.GetRed(), nG = aFillCol.GetGreen(), nB = aFillCol.GetBlue();
     474             :                             long                nX, nY;
     475             : 
     476           0 :                             if( aPaint.GetBitCount() <= 8 )
     477             :                             {
     478           0 :                                 const BitmapPalette&    rPal = pW->GetPalette();
     479           0 :                                 const sal_uInt16            nCount = rPal.GetEntryCount();
     480           0 :                                 BitmapColor*            pMap = (BitmapColor*) new sal_uInt8[ nCount * sizeof( BitmapColor ) ];
     481             : 
     482           0 :                                 for( sal_uInt16 i = 0; i < nCount; i++ )
     483             :                                 {
     484           0 :                                     BitmapColor aCol( rPal[ i ] );
     485           0 :                                     pMap[ i ] = BitmapColor( (sal_uInt8) rPal.GetBestIndex( aCol.Merge( aFillCol, cTrans ) ) );
     486           0 :                                 }
     487             : 
     488           0 :                                 if( pR->GetScanlineFormat() == BMP_FORMAT_1BIT_MSB_PAL &&
     489           0 :                                     pW->GetScanlineFormat() == BMP_FORMAT_8BIT_PAL )
     490             :                                 {
     491           0 :                                     const sal_uInt8 cBlack = aBlack.GetIndex();
     492             : 
     493           0 :                                     for( nY = 0; nY < nHeight; nY++ )
     494             :                                     {
     495           0 :                                         Scanline    pWScan = pW->GetScanline( nY );
     496           0 :                                         Scanline    pRScan = pR->GetScanline( nY );
     497           0 :                                         sal_uInt8       cBit = 128;
     498             : 
     499           0 :                                         for( nX = 0; nX < nWidth; nX++, cBit >>= 1, pWScan++ )
     500             :                                         {
     501           0 :                                             if( !cBit )
     502           0 :                                                 cBit = 128, pRScan++;
     503             : 
     504           0 :                                             if( ( *pRScan & cBit ) == cBlack )
     505           0 :                                                 *pWScan = (sal_uInt8) pMap[ *pWScan ].GetIndex();
     506             :                                         }
     507             :                                     }
     508             :                                 }
     509             :                                 else
     510             :                                 {
     511           0 :                                     for( nY = 0; nY < nHeight; nY++ )
     512           0 :                                         for( nX = 0; nX < nWidth; nX++ )
     513           0 :                                             if( pR->GetPixel( nY, nX ) == aBlack )
     514           0 :                                                 pW->SetPixel( nY, nX, pMap[ pW->GetPixel( nY, nX ).GetIndex() ] );
     515             :                                 }
     516             : 
     517           0 :                                 delete[] (sal_uInt8*) pMap;
     518             :                             }
     519             :                             else
     520             :                             {
     521           0 :                                 if( pR->GetScanlineFormat() == BMP_FORMAT_1BIT_MSB_PAL &&
     522           0 :                                     pW->GetScanlineFormat() == BMP_FORMAT_24BIT_TC_BGR )
     523             :                                 {
     524           0 :                                     const sal_uInt8 cBlack = aBlack.GetIndex();
     525             : 
     526           0 :                                     for( nY = 0; nY < nHeight; nY++ )
     527             :                                     {
     528           0 :                                         Scanline    pWScan = pW->GetScanline( nY );
     529           0 :                                         Scanline    pRScan = pR->GetScanline( nY );
     530           0 :                                         sal_uInt8       cBit = 128;
     531             : 
     532           0 :                                         for( nX = 0; nX < nWidth; nX++, cBit >>= 1, pWScan += 3 )
     533             :                                         {
     534           0 :                                             if( !cBit )
     535           0 :                                                 cBit = 128, pRScan++;
     536             : 
     537           0 :                                             if( ( *pRScan & cBit ) == cBlack )
     538             :                                             {
     539           0 :                                                 pWScan[ 0 ] = COLOR_CHANNEL_MERGE( pWScan[ 0 ], nB, cTrans );
     540           0 :                                                 pWScan[ 1 ] = COLOR_CHANNEL_MERGE( pWScan[ 1 ], nG, cTrans );
     541           0 :                                                 pWScan[ 2 ] = COLOR_CHANNEL_MERGE( pWScan[ 2 ], nR, cTrans );
     542             :                                             }
     543             :                                         }
     544             :                                     }
     545             :                                 }
     546             :                                 else
     547             :                                 {
     548           0 :                                     for( nY = 0; nY < nHeight; nY++ )
     549             :                                     {
     550           0 :                                         for( nX = 0; nX < nWidth; nX++ )
     551             :                                         {
     552           0 :                                             if( pR->GetPixel( nY, nX ) == aBlack )
     553             :                                             {
     554           0 :                                                 aPixCol = pW->GetColor( nY, nX );
     555           0 :                                                 pW->SetPixel( nY, nX, aPixCol.Merge( aFillCol, cTrans ) );
     556             :                                             }
     557             :                                         }
     558             :                                     }
     559             :                                 }
     560           0 :                             }
     561             :                         }
     562             : 
     563           0 :                         aPolyMask.ReleaseAccess( pR );
     564           0 :                         aPaint.ReleaseAccess( pW );
     565             : 
     566           0 :                         DrawBitmap( aDstRect.TopLeft(), aPaint );
     567             : 
     568           0 :                         EnableMapMode( bOldMap );
     569             : 
     570           0 :                         if( mbLineColor )
     571             :                         {
     572           0 :                             Push( PUSH_FILLCOLOR );
     573           0 :                             SetFillColor();
     574           0 :                             DrawPolyPolygon( rPolyPoly );
     575           0 :                             Pop();
     576             :                         }
     577           0 :                     }
     578             :                 }
     579             :                 else
     580           0 :                     DrawPolyPolygon( rPolyPoly );
     581             :             }
     582           0 :         }
     583             :     }
     584             : 
     585           0 :     mpMetaFile = pOldMetaFile;
     586             : 
     587             :     // #110958# Restore disabled alpha VDev
     588           0 :     mpAlphaVDev = pOldAlphaVDev;
     589             : 
     590             :     // #110958# Apply alpha value also to VDev alpha channel
     591           0 :     if( mpAlphaVDev )
     592             :     {
     593           0 :         const Color aFillCol( mpAlphaVDev->GetFillColor() );
     594           0 :         mpAlphaVDev->SetFillColor( Color(sal::static_int_cast<sal_uInt8>(255*nTransparencePercent/100),
     595           0 :                                          sal::static_int_cast<sal_uInt8>(255*nTransparencePercent/100),
     596           0 :                                          sal::static_int_cast<sal_uInt8>(255*nTransparencePercent/100)) );
     597             : 
     598           0 :         mpAlphaVDev->DrawTransparent( rPolyPoly, nTransparencePercent );
     599             : 
     600           0 :         mpAlphaVDev->SetFillColor( aFillCol );
     601             :     }
     602             : }
     603             : 
     604             : // -----------------------------------------------------------------------
     605             : 
     606           0 : void OutputDevice::DrawTransparent( const GDIMetaFile& rMtf, const Point& rPos,
     607             :                                     const Size& rSize, const Gradient& rTransparenceGradient )
     608             : {
     609             :     OSL_TRACE( "OutputDevice::DrawTransparent()" );
     610             :     DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
     611             : 
     612           0 :     const Color aBlack( COL_BLACK );
     613             : 
     614           0 :     if( mpMetaFile )
     615           0 :         mpMetaFile->AddAction( new MetaFloatTransparentAction( rMtf, rPos, rSize, rTransparenceGradient ) );
     616             : 
     617           0 :     if( ( rTransparenceGradient.GetStartColor() == aBlack && rTransparenceGradient.GetEndColor() == aBlack ) ||
     618             :         ( mnDrawMode & ( DRAWMODE_NOTRANSPARENCY ) ) )
     619             :     {
     620           0 :         ( (GDIMetaFile&) rMtf ).WindStart();
     621           0 :         ( (GDIMetaFile&) rMtf ).Play( this, rPos, rSize );
     622           0 :         ( (GDIMetaFile&) rMtf ).WindStart();
     623             :     }
     624             :     else
     625             :     {
     626           0 :         GDIMetaFile*    pOldMetaFile = mpMetaFile;
     627           0 :         Rectangle       aOutRect( LogicToPixel( rPos ), LogicToPixel( rSize ) );
     628           0 :         Point           aPoint;
     629           0 :         Rectangle       aDstRect( aPoint, GetOutputSizePixel() );
     630             : 
     631           0 :         mpMetaFile = NULL;
     632           0 :         aDstRect.Intersection( aOutRect );
     633             : 
     634           0 :         if( OUTDEV_WINDOW == meOutDevType )
     635             :         {
     636           0 :             const Region aPaintRgn( ( (Window*) this )->GetPaintRegion() );
     637             : 
     638           0 :             if( !aPaintRgn.IsNull() )
     639           0 :                 aDstRect.Intersection( LogicToPixel( aPaintRgn.GetBoundRect() ) );
     640             :         }
     641             : 
     642           0 :         if( !aDstRect.IsEmpty() )
     643             :         {
     644           0 :             VirtualDevice* pVDev = new VirtualDevice;
     645             : 
     646           0 :             ((OutputDevice*)pVDev)->mnDPIX = mnDPIX;
     647           0 :             ((OutputDevice*)pVDev)->mnDPIY = mnDPIY;
     648             : 
     649           0 :             if( pVDev->SetOutputSizePixel( aDstRect.GetSize() ) )
     650             :             {
     651           0 :                 if(GetAntialiasing())
     652             :                 {
     653             :                     // #i102109#
     654             :                     // For MetaFile replay (see task) it may now be neccessary to take
     655             :                     // into account that the content is AntiAlialised and needs to be masked
     656             :                     // like that. Instead of masking, i will use a copy-modify-paste cycle
     657             :                     // here (as i already use in the VclPrimiziveRenderer with successs)
     658           0 :                     pVDev->SetAntialiasing(GetAntialiasing());
     659             : 
     660             :                     // create MapMode for buffer (offset needed) and set
     661           0 :                     MapMode aMap(GetMapMode());
     662           0 :                     const Point aOutPos(PixelToLogic(aDstRect.TopLeft()));
     663           0 :                     aMap.SetOrigin(Point(-aOutPos.X(), -aOutPos.Y()));
     664           0 :                     pVDev->SetMapMode(aMap);
     665             : 
     666             :                     // copy MapMode state and disable for target
     667           0 :                     const bool bOrigMapModeEnabled(IsMapModeEnabled());
     668           0 :                     EnableMapMode(false);
     669             : 
     670             :                     // copy MapMode state and disable for buffer
     671           0 :                     const bool bBufferMapModeEnabled(pVDev->IsMapModeEnabled());
     672           0 :                     pVDev->EnableMapMode(false);
     673             : 
     674             :                     // copy content from original to buffer
     675             :                     pVDev->DrawOutDev(
     676           0 :                         aPoint, pVDev->GetOutputSizePixel(), // dest
     677           0 :                         aDstRect.TopLeft(), pVDev->GetOutputSizePixel(), // source
     678           0 :                         *this);
     679             : 
     680             :                     // draw MetaFile to buffer
     681           0 :                     pVDev->EnableMapMode(bBufferMapModeEnabled);
     682           0 :                     ((GDIMetaFile&)rMtf).WindStart();
     683           0 :                     ((GDIMetaFile&)rMtf).Play(pVDev, rPos, rSize);
     684           0 :                     ((GDIMetaFile&)rMtf).WindStart();
     685             : 
     686             :                     // get content bitmap from buffer
     687           0 :                     pVDev->EnableMapMode(false);
     688           0 :                     const Bitmap aPaint(pVDev->GetBitmap(aPoint, pVDev->GetOutputSizePixel()));
     689             : 
     690             :                     // create alpha mask from gradient and get as Bitmap
     691           0 :                     pVDev->EnableMapMode(bBufferMapModeEnabled);
     692           0 :                     pVDev->SetDrawMode(DRAWMODE_GRAYGRADIENT);
     693           0 :                     pVDev->DrawGradient(Rectangle(rPos, rSize), rTransparenceGradient);
     694           0 :                     pVDev->SetDrawMode(DRAWMODE_DEFAULT);
     695           0 :                     pVDev->EnableMapMode(false);
     696           0 :                     const AlphaMask aAlpha(pVDev->GetBitmap(aPoint, pVDev->GetOutputSizePixel()));
     697             : 
     698           0 :                     delete pVDev;
     699             : 
     700             :                     // draw masked content to target and restore MapMode
     701           0 :                     DrawBitmapEx(aDstRect.TopLeft(), BitmapEx(aPaint, aAlpha));
     702           0 :                     EnableMapMode(bOrigMapModeEnabled);
     703             :                 }
     704             :                 else
     705             :                 {
     706           0 :                     Bitmap      aPaint, aMask;
     707           0 :                     AlphaMask   aAlpha;
     708           0 :                     MapMode     aMap( GetMapMode() );
     709           0 :                     Point       aOutPos( PixelToLogic( aDstRect.TopLeft() ) );
     710           0 :                     const sal_Bool  bOldMap = mbMap;
     711             : 
     712           0 :                     aMap.SetOrigin( Point( -aOutPos.X(), -aOutPos.Y() ) );
     713           0 :                     pVDev->SetMapMode( aMap );
     714           0 :                     const sal_Bool  bVDevOldMap = pVDev->IsMapModeEnabled();
     715             : 
     716             :                     // create paint bitmap
     717           0 :                     ( (GDIMetaFile&) rMtf ).WindStart();
     718           0 :                     ( (GDIMetaFile&) rMtf ).Play( pVDev, rPos, rSize );
     719           0 :                     ( (GDIMetaFile&) rMtf ).WindStart();
     720           0 :                     pVDev->EnableMapMode( sal_False );
     721           0 :                     aPaint = pVDev->GetBitmap( Point(), pVDev->GetOutputSizePixel() );
     722           0 :                     pVDev->EnableMapMode( bVDevOldMap ); // #i35331#: MUST NOT use EnableMapMode( sal_True ) here!
     723             : 
     724             :                     // create mask bitmap
     725           0 :                     pVDev->SetLineColor( COL_BLACK );
     726           0 :                     pVDev->SetFillColor( COL_BLACK );
     727           0 :                     pVDev->DrawRect( Rectangle( pVDev->PixelToLogic( Point() ), pVDev->GetOutputSize() ) );
     728             :                     pVDev->SetDrawMode( DRAWMODE_WHITELINE | DRAWMODE_WHITEFILL | DRAWMODE_WHITETEXT |
     729           0 :                                         DRAWMODE_WHITEBITMAP | DRAWMODE_WHITEGRADIENT );
     730           0 :                     ( (GDIMetaFile&) rMtf ).WindStart();
     731           0 :                     ( (GDIMetaFile&) rMtf ).Play( pVDev, rPos, rSize );
     732           0 :                     ( (GDIMetaFile&) rMtf ).WindStart();
     733           0 :                     pVDev->EnableMapMode( sal_False );
     734           0 :                     aMask = pVDev->GetBitmap( Point(), pVDev->GetOutputSizePixel() );
     735           0 :                     pVDev->EnableMapMode( bVDevOldMap ); // #i35331#: MUST NOT use EnableMapMode( sal_True ) here!
     736             : 
     737             :                     // create alpha mask from gradient
     738           0 :                     pVDev->SetDrawMode( DRAWMODE_GRAYGRADIENT );
     739           0 :                     pVDev->DrawGradient( Rectangle( rPos, rSize ), rTransparenceGradient );
     740           0 :                     pVDev->SetDrawMode( DRAWMODE_DEFAULT );
     741           0 :                     pVDev->EnableMapMode( sal_False );
     742           0 :                     pVDev->DrawMask( Point(), pVDev->GetOutputSizePixel(), aMask, Color( COL_WHITE ) );
     743             : 
     744           0 :                     aAlpha = pVDev->GetBitmap( Point(), pVDev->GetOutputSizePixel() );
     745             : 
     746           0 :                     delete pVDev;
     747             : 
     748           0 :                     EnableMapMode( sal_False );
     749           0 :                     DrawBitmapEx( aDstRect.TopLeft(), BitmapEx( aPaint, aAlpha ) );
     750           0 :                     EnableMapMode( bOldMap );
     751             :                 }
     752             :             }
     753             :             else
     754           0 :                 delete pVDev;
     755             :         }
     756             : 
     757           0 :         mpMetaFile = pOldMetaFile;
     758             :     }
     759           0 : }
     760             : 
     761             : // -----------------------------------------------------------------------
     762             : 
     763       11924 : void OutputDevice::ImplDrawColorWallpaper( long nX, long nY,
     764             :                                            long nWidth, long nHeight,
     765             :                                            const Wallpaper& rWallpaper )
     766             : {
     767             :     // Wallpaper ohne Umrandung zeichnen
     768       11924 :     Color aOldLineColor = GetLineColor();
     769       11924 :     Color aOldFillColor = GetFillColor();
     770       11924 :     SetLineColor();
     771       11924 :     SetFillColor( rWallpaper.GetColor() );
     772       11924 :     sal_Bool bMap = mbMap;
     773       11924 :     EnableMapMode( sal_False );
     774       11924 :     DrawRect( Rectangle( Point( nX, nY ), Size( nWidth, nHeight ) ) );
     775       11924 :     SetLineColor( aOldLineColor );
     776       11924 :     SetFillColor( aOldFillColor );
     777       11924 :     EnableMapMode( bMap );
     778       11924 : }
     779             : 
     780             : // -----------------------------------------------------------------------
     781             : 
     782           0 : void OutputDevice::ImplDrawBitmapWallpaper( long nX, long nY,
     783             :                                             long nWidth, long nHeight,
     784             :                                             const Wallpaper& rWallpaper )
     785             : {
     786           0 :     BitmapEx                aBmpEx;
     787           0 :     const BitmapEx*         pCached = rWallpaper.ImplGetImpWallpaper()->ImplGetCachedBitmap();
     788           0 :     Point                   aPos;
     789           0 :     Size                    aSize;
     790           0 :     GDIMetaFile*            pOldMetaFile = mpMetaFile;
     791           0 :     const WallpaperStyle    eStyle = rWallpaper.GetStyle();
     792           0 :     const sal_Bool              bOldMap = mbMap;
     793           0 :     sal_Bool                    bDrawn = sal_False;
     794           0 :     sal_Bool                    bDrawGradientBackground = sal_False;
     795           0 :     sal_Bool                    bDrawColorBackground = sal_False;
     796             : 
     797           0 :     if( pCached )
     798           0 :         aBmpEx = *pCached;
     799             :     else
     800           0 :         aBmpEx = rWallpaper.GetBitmap();
     801             : 
     802           0 :     const long nBmpWidth = aBmpEx.GetSizePixel().Width();
     803           0 :     const long nBmpHeight = aBmpEx.GetSizePixel().Height();
     804           0 :     const sal_Bool bTransparent = aBmpEx.IsTransparent();
     805             : 
     806             :     // draw background
     807           0 :     if( bTransparent )
     808             :     {
     809           0 :         if( rWallpaper.IsGradient() )
     810           0 :             bDrawGradientBackground = sal_True;
     811             :         else
     812             :         {
     813           0 :             if( !pCached && !rWallpaper.GetColor().GetTransparency() )
     814             :             {
     815           0 :                 VirtualDevice aVDev( *this );
     816           0 :                 aVDev.SetBackground( rWallpaper.GetColor() );
     817           0 :                 aVDev.SetOutputSizePixel( Size( nBmpWidth, nBmpHeight ) );
     818           0 :                 aVDev.DrawBitmapEx( Point(), aBmpEx );
     819           0 :                 aBmpEx = aVDev.GetBitmap( Point(), aVDev.GetOutputSizePixel() );
     820             :             }
     821             : 
     822           0 :             bDrawColorBackground = sal_True;
     823             :         }
     824             :     }
     825           0 :     else if( eStyle != WALLPAPER_TILE && eStyle != WALLPAPER_SCALE )
     826             :     {
     827           0 :         if( rWallpaper.IsGradient() )
     828           0 :             bDrawGradientBackground = sal_True;
     829             :         else
     830           0 :             bDrawColorBackground = sal_True;
     831             :     }
     832             : 
     833             :     // background of bitmap?
     834           0 :     if( bDrawGradientBackground )
     835           0 :         ImplDrawGradientWallpaper( nX, nY, nWidth, nHeight, rWallpaper );
     836           0 :     else if( bDrawColorBackground && bTransparent )
     837             :     {
     838           0 :         ImplDrawColorWallpaper( nX, nY, nWidth, nHeight, rWallpaper );
     839           0 :         bDrawColorBackground = sal_False;
     840             :     }
     841             : 
     842             :     // calc pos and size
     843           0 :     if( rWallpaper.IsRect() )
     844             :     {
     845           0 :         const Rectangle aBound( LogicToPixel( rWallpaper.GetRect() ) );
     846           0 :         aPos = aBound.TopLeft();
     847           0 :         aSize = aBound.GetSize();
     848             :     }
     849             :     else
     850             :     {
     851           0 :         aPos = Point( nX, nY );
     852           0 :         aSize = Size( nWidth, nHeight );
     853             :     }
     854             : 
     855           0 :     mpMetaFile = NULL;
     856           0 :     EnableMapMode( sal_False );
     857           0 :     Push( PUSH_CLIPREGION );
     858           0 :     IntersectClipRegion( Rectangle( Point( nX, nY ), Size( nWidth, nHeight ) ) );
     859             : 
     860           0 :     switch( eStyle )
     861             :     {
     862             :         case( WALLPAPER_SCALE ):
     863             :         {
     864           0 :             if( !pCached || ( pCached->GetSizePixel() != aSize ) )
     865             :             {
     866           0 :                 if( pCached )
     867           0 :                     rWallpaper.ImplGetImpWallpaper()->ImplReleaseCachedBitmap();
     868             : 
     869           0 :                 aBmpEx = rWallpaper.GetBitmap();
     870           0 :                 aBmpEx.Scale( aSize );
     871           0 :                 aBmpEx = BitmapEx( aBmpEx.GetBitmap().CreateDisplayBitmap( this ), aBmpEx.GetMask() );
     872             :             }
     873             :         }
     874           0 :         break;
     875             : 
     876             :         case( WALLPAPER_TOPLEFT ):
     877           0 :         break;
     878             : 
     879             :         case( WALLPAPER_TOP ):
     880           0 :             aPos.X() += ( aSize.Width() - nBmpWidth ) >> 1;
     881           0 :         break;
     882             : 
     883             :         case( WALLPAPER_TOPRIGHT ):
     884           0 :             aPos.X() += ( aSize.Width() - nBmpWidth );
     885           0 :         break;
     886             : 
     887             :         case( WALLPAPER_LEFT ):
     888           0 :             aPos.Y() += ( aSize.Height() - nBmpHeight ) >> 1;
     889           0 :         break;
     890             : 
     891             :         case( WALLPAPER_CENTER ):
     892             :         {
     893           0 :             aPos.X() += ( aSize.Width() - nBmpWidth ) >> 1;
     894           0 :             aPos.Y() += ( aSize.Height() - nBmpHeight ) >> 1;
     895             :         }
     896           0 :         break;
     897             : 
     898             :         case( WALLPAPER_RIGHT ):
     899             :         {
     900           0 :             aPos.X() += ( aSize.Width() - nBmpWidth );
     901           0 :             aPos.Y() += ( aSize.Height() - nBmpHeight ) >> 1;
     902             :         }
     903           0 :         break;
     904             : 
     905             :         case( WALLPAPER_BOTTOMLEFT ):
     906           0 :             aPos.Y() += ( aSize.Height() - nBmpHeight );
     907           0 :         break;
     908             : 
     909             :         case( WALLPAPER_BOTTOM ):
     910             :         {
     911           0 :             aPos.X() += ( aSize.Width() - nBmpWidth ) >> 1;
     912           0 :             aPos.Y() += ( aSize.Height() - nBmpHeight );
     913             :         }
     914           0 :         break;
     915             : 
     916             :         case( WALLPAPER_BOTTOMRIGHT ):
     917             :         {
     918           0 :             aPos.X() += ( aSize.Width() - nBmpWidth );
     919           0 :             aPos.Y() += ( aSize.Height() - nBmpHeight );
     920             :         }
     921           0 :         break;
     922             : 
     923             :         default:
     924             :         {
     925           0 :             const long  nRight = nX + nWidth - 1L;
     926           0 :             const long  nBottom = nY + nHeight - 1L;
     927             :             long        nFirstX;
     928             :             long        nFirstY;
     929             : 
     930           0 :             if( eStyle == WALLPAPER_TILE )
     931             :             {
     932           0 :                 nFirstX = aPos.X();
     933           0 :                 nFirstY = aPos.Y();
     934             :             }
     935             :             else
     936             :             {
     937           0 :                 nFirstX = aPos.X() + ( ( aSize.Width() - nBmpWidth ) >> 1 );
     938           0 :                 nFirstY = aPos.Y() + ( ( aSize.Height() - nBmpHeight ) >> 1 );
     939             :             }
     940             : 
     941           0 :             const long  nOffX = ( nFirstX - nX ) % nBmpWidth;
     942           0 :             const long  nOffY = ( nFirstY - nY ) % nBmpHeight;
     943           0 :             long        nStartX = nX + nOffX;
     944           0 :             long        nStartY = nY + nOffY;
     945             : 
     946           0 :             if( nOffX > 0L )
     947           0 :                 nStartX -= nBmpWidth;
     948             : 
     949           0 :             if( nOffY > 0L )
     950           0 :                 nStartY -= nBmpHeight;
     951             : 
     952           0 :             for( long nBmpY = nStartY; nBmpY <= nBottom; nBmpY += nBmpHeight )
     953           0 :                 for( long nBmpX = nStartX; nBmpX <= nRight; nBmpX += nBmpWidth )
     954           0 :                     DrawBitmapEx( Point( nBmpX, nBmpY ), aBmpEx );
     955             : 
     956           0 :             bDrawn = sal_True;
     957             :         }
     958           0 :         break;
     959             :     }
     960             : 
     961           0 :     if( !bDrawn )
     962             :     {
     963             :         // optimized for non-transparent bitmaps
     964           0 :         if( bDrawColorBackground )
     965             :         {
     966           0 :             const Size      aBmpSize( aBmpEx.GetSizePixel() );
     967           0 :             const Point     aTmpPoint;
     968           0 :             const Rectangle aOutRect( aTmpPoint, GetOutputSizePixel() );
     969           0 :             const Rectangle aColRect( Point( nX, nY ), Size( nWidth, nHeight ) );
     970           0 :             Rectangle       aWorkRect;
     971             : 
     972           0 :             aWorkRect = Rectangle( 0, 0, aOutRect.Right(), aPos.Y() - 1L );
     973           0 :             aWorkRect.Justify();
     974           0 :             aWorkRect.Intersection( aColRect );
     975           0 :             if( !aWorkRect.IsEmpty() )
     976             :             {
     977           0 :                 ImplDrawColorWallpaper( aWorkRect.Left(), aWorkRect.Top(),
     978             :                                         aWorkRect.GetWidth(), aWorkRect.GetHeight(),
     979           0 :                                         rWallpaper );
     980             :             }
     981             : 
     982           0 :             aWorkRect = Rectangle( 0, aPos.Y(), aPos.X() - 1L, aPos.Y() + aBmpSize.Height() - 1L );
     983           0 :             aWorkRect.Justify();
     984           0 :             aWorkRect.Intersection( aColRect );
     985           0 :             if( !aWorkRect.IsEmpty() )
     986             :             {
     987           0 :                 ImplDrawColorWallpaper( aWorkRect.Left(), aWorkRect.Top(),
     988             :                                         aWorkRect.GetWidth(), aWorkRect.GetHeight(),
     989           0 :                                         rWallpaper );
     990             :             }
     991             : 
     992           0 :             aWorkRect = Rectangle( aPos.X() + aBmpSize.Width(), aPos.Y(), aOutRect.Right(), aPos.Y() + aBmpSize.Height() - 1L );
     993           0 :             aWorkRect.Justify();
     994           0 :             aWorkRect.Intersection( aColRect );
     995           0 :             if( !aWorkRect.IsEmpty() )
     996             :             {
     997           0 :                 ImplDrawColorWallpaper( aWorkRect.Left(), aWorkRect.Top(),
     998             :                                         aWorkRect.GetWidth(), aWorkRect.GetHeight(),
     999           0 :                                         rWallpaper );
    1000             :             }
    1001             : 
    1002           0 :             aWorkRect = Rectangle( 0, aPos.Y() + aBmpSize.Height(), aOutRect.Right(), aOutRect.Bottom() );
    1003           0 :             aWorkRect.Justify();
    1004           0 :             aWorkRect.Intersection( aColRect );
    1005           0 :             if( !aWorkRect.IsEmpty() )
    1006             :             {
    1007           0 :                 ImplDrawColorWallpaper( aWorkRect.Left(), aWorkRect.Top(),
    1008             :                                         aWorkRect.GetWidth(), aWorkRect.GetHeight(),
    1009           0 :                                         rWallpaper );
    1010             :             }
    1011             :         }
    1012             : 
    1013           0 :         DrawBitmapEx( aPos, aBmpEx );
    1014             :     }
    1015             : 
    1016           0 :     rWallpaper.ImplGetImpWallpaper()->ImplSetCachedBitmap( aBmpEx );
    1017             : 
    1018           0 :     Pop();
    1019           0 :     EnableMapMode( bOldMap );
    1020           0 :     mpMetaFile = pOldMetaFile;
    1021           0 : }
    1022             : 
    1023             : // -----------------------------------------------------------------------
    1024             : 
    1025         612 : void OutputDevice::ImplDrawGradientWallpaper( long nX, long nY,
    1026             :                                               long nWidth, long nHeight,
    1027             :                                               const Wallpaper& rWallpaper )
    1028             : {
    1029         612 :     Rectangle       aBound;
    1030         612 :     GDIMetaFile*    pOldMetaFile = mpMetaFile;
    1031         612 :     const sal_Bool      bOldMap = mbMap;
    1032         612 :     sal_Bool            bNeedGradient = sal_True;
    1033             : 
    1034         612 :         aBound = Rectangle( Point( nX, nY ), Size( nWidth, nHeight ) );
    1035             : 
    1036         612 :     mpMetaFile = NULL;
    1037         612 :     EnableMapMode( sal_False );
    1038         612 :     Push( PUSH_CLIPREGION );
    1039         612 :     IntersectClipRegion( Rectangle( Point( nX, nY ), Size( nWidth, nHeight ) ) );
    1040             : 
    1041         612 :     if( OUTDEV_WINDOW == meOutDevType && rWallpaper.GetStyle() == WALLPAPER_APPLICATIONGRADIENT )
    1042             :     {
    1043         612 :         Window *pWin = dynamic_cast< Window* >( this );
    1044         612 :         if( pWin )
    1045             :         {
    1046             :             // limit gradient to useful size, so that it still can be noticed
    1047             :             // in maximized windows
    1048         612 :             long gradientWidth = pWin->GetDesktopRectPixel().GetSize().Width();
    1049         612 :             if( gradientWidth > 1024 )
    1050           0 :                 gradientWidth = 1024;
    1051         612 :             if( mnOutOffX+nWidth > gradientWidth )
    1052           0 :                 ImplDrawColorWallpaper(  nX, nY, nWidth, nHeight, rWallpaper.GetGradient().GetEndColor() );
    1053         612 :             if( mnOutOffX > gradientWidth )
    1054           0 :                 bNeedGradient = sal_False;
    1055             :             else
    1056         612 :                 aBound = Rectangle( Point( -mnOutOffX, nY ), Size( gradientWidth, nHeight ) );
    1057             :         }
    1058             :     }
    1059             : 
    1060         612 :     if( bNeedGradient )
    1061         612 :         DrawGradient( aBound, rWallpaper.GetGradient() );
    1062             : 
    1063         612 :     Pop();
    1064         612 :     EnableMapMode( bOldMap );
    1065         612 :     mpMetaFile = pOldMetaFile;
    1066         612 : }
    1067             : 
    1068             : // -----------------------------------------------------------------------
    1069             : 
    1070       12536 : void OutputDevice::ImplDrawWallpaper( long nX, long nY,
    1071             :                                       long nWidth, long nHeight,
    1072             :                                       const Wallpaper& rWallpaper )
    1073             : {
    1074       12536 :     if( rWallpaper.IsBitmap() )
    1075           0 :         ImplDrawBitmapWallpaper( nX, nY, nWidth, nHeight, rWallpaper );
    1076       12536 :     else if( rWallpaper.IsGradient() )
    1077         612 :         ImplDrawGradientWallpaper( nX, nY, nWidth, nHeight, rWallpaper );
    1078             :     else
    1079       11924 :         ImplDrawColorWallpaper(  nX, nY, nWidth, nHeight, rWallpaper );
    1080       12536 : }
    1081             : 
    1082             : // -----------------------------------------------------------------------
    1083             : 
    1084         964 : void OutputDevice::DrawWallpaper( const Rectangle& rRect,
    1085             :                                   const Wallpaper& rWallpaper )
    1086             : {
    1087         964 :     if ( mpMetaFile )
    1088           0 :         mpMetaFile->AddAction( new MetaWallpaperAction( rRect, rWallpaper ) );
    1089             : 
    1090         964 :     if ( !IsDeviceOutputNecessary() || ImplIsRecordLayout() )
    1091         964 :         return;
    1092             : 
    1093         964 :     if ( rWallpaper.GetStyle() != WALLPAPER_NULL )
    1094             :     {
    1095         960 :         Rectangle aRect = LogicToPixel( rRect );
    1096         960 :         aRect.Justify();
    1097             : 
    1098         960 :         if ( !aRect.IsEmpty() )
    1099             :         {
    1100        1920 :             ImplDrawWallpaper( aRect.Left(), aRect.Top(), aRect.GetWidth(), aRect.GetHeight(),
    1101        2880 :                                rWallpaper );
    1102             :         }
    1103             :     }
    1104             : 
    1105         964 :     if( mpAlphaVDev )
    1106           0 :         mpAlphaVDev->DrawWallpaper( rRect, rWallpaper );
    1107             : }
    1108             : 
    1109             : // -----------------------------------------------------------------------
    1110             : 
    1111       11576 : void OutputDevice::Erase()
    1112             : {
    1113       11576 :     if ( !IsDeviceOutputNecessary() || ImplIsRecordLayout() )
    1114       11576 :         return;
    1115             : 
    1116       11576 :     sal_Bool bNativeOK = sal_False;
    1117             : 
    1118       11576 :     if( meOutDevType == OUTDEV_WINDOW )
    1119             :     {
    1120        3534 :         Window* pWindow = static_cast<Window*>(this);
    1121        3534 :         ControlPart aCtrlPart = pWindow->ImplGetWindowImpl()->mnNativeBackground;
    1122        3534 :         if( aCtrlPart != 0 && ! pWindow->IsControlBackground() )
    1123             :         {
    1124           0 :             ImplControlValue    aControlValue;
    1125           0 :             Point               aGcc3WorkaroundTemporary;
    1126           0 :             Rectangle           aCtrlRegion( aGcc3WorkaroundTemporary, GetOutputSizePixel() );
    1127           0 :             ControlState        nState = 0;
    1128             : 
    1129           0 :             if( pWindow->IsEnabled() )              nState |= CTRL_STATE_ENABLED;
    1130             :             bNativeOK = pWindow->DrawNativeControl( CTRL_WINDOW_BACKGROUND, aCtrlPart, aCtrlRegion,
    1131           0 :                                                     nState, aControlValue, rtl::OUString() );
    1132             :         }
    1133             :     }
    1134             : 
    1135       11576 :     if ( mbBackground && ! bNativeOK )
    1136             :     {
    1137       11576 :         RasterOp eRasterOp = GetRasterOp();
    1138       11576 :         if ( eRasterOp != ROP_OVERPAINT )
    1139           0 :             SetRasterOp( ROP_OVERPAINT );
    1140       11576 :         ImplDrawWallpaper( 0, 0, mnOutWidth, mnOutHeight, maBackground );
    1141       11576 :         if ( eRasterOp != ROP_OVERPAINT )
    1142           0 :             SetRasterOp( eRasterOp );
    1143             :     }
    1144             : 
    1145       11576 :     if( mpAlphaVDev )
    1146           0 :         mpAlphaVDev->Erase();
    1147             : }
    1148             : 
    1149             : // -----------------------------------------------------------------------
    1150             : 
    1151           0 : bool OutputDevice::DrawEPS( const Point& rPoint, const Size& rSize,
    1152             :                             const GfxLink& rGfxLink, GDIMetaFile* pSubst )
    1153             : {
    1154             :     OSL_TRACE( "OutputDevice::DrawEPS()" );
    1155             : 
    1156           0 :     bool bDrawn(true);
    1157             : 
    1158           0 :     if ( mpMetaFile )
    1159             :     {
    1160           0 :         GDIMetaFile aSubst;
    1161             : 
    1162           0 :         if( pSubst )
    1163           0 :             aSubst = *pSubst;
    1164             : 
    1165           0 :         mpMetaFile->AddAction( new MetaEPSAction( rPoint, rSize, rGfxLink, aSubst ) );
    1166             :     }
    1167             : 
    1168           0 :     if ( !IsDeviceOutputNecessary() || ImplIsRecordLayout() )
    1169           0 :         return bDrawn;
    1170             : 
    1171           0 :     if( mbOutputClipped )
    1172           0 :         return bDrawn;
    1173             : 
    1174           0 :     Rectangle aRect( ImplLogicToDevicePixel( Rectangle( rPoint, rSize ) ) );
    1175             : 
    1176           0 :     if( !aRect.IsEmpty() )
    1177             :     {
    1178             :         // draw the real EPS graphics
    1179           0 :         if( rGfxLink.GetData() && rGfxLink.GetDataSize() )
    1180             :         {
    1181           0 :             if( !mpGraphics && !ImplGetGraphics() )
    1182           0 :                 return bDrawn;
    1183             : 
    1184           0 :             if( mbInitClipRegion )
    1185           0 :                 ImplInitClipRegion();
    1186             : 
    1187           0 :             aRect.Justify();
    1188           0 :             bDrawn = mpGraphics->DrawEPS( aRect.Left(), aRect.Top(), aRect.GetWidth(), aRect.GetHeight(),
    1189           0 :                          (sal_uInt8*) rGfxLink.GetData(), rGfxLink.GetDataSize(), this );
    1190             :         }
    1191             : 
    1192             :         // else draw the substitution graphics
    1193           0 :         if( !bDrawn && pSubst )
    1194             :         {
    1195           0 :             GDIMetaFile* pOldMetaFile = mpMetaFile;
    1196             : 
    1197           0 :             mpMetaFile = NULL;
    1198           0 :             Graphic( *pSubst ).Draw( this, rPoint, rSize );
    1199           0 :             mpMetaFile = pOldMetaFile;
    1200             :         }
    1201             :     }
    1202             : 
    1203           0 :     if( mpAlphaVDev )
    1204           0 :         mpAlphaVDev->DrawEPS( rPoint, rSize, rGfxLink, pSubst );
    1205             : 
    1206           0 :     return bDrawn;
    1207             : }
    1208             : 
    1209             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10