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