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