[Libreoffice-commits] core.git: Branch 'private/tbsdy/seperateoutdev' - 77 commits - accessibility/inc accessibility/source android/Bootstrap avmedia/source chart2/source comphelper/source cppuhelper/qa cui/source dbaccess/source editeng/source embeddedobj/source embedserv/source external/glew formula/source framework/inc framework/source include/cppuhelper include/formula include/linguistic include/sfx2 include/svtools include/svx include/vcl include/xmloff linguistic/source oox/CustomTarget_generated.mk oox/Module_oox.mk oox/Package_generated.mk oox/source reportdesign/source Repository.mk sc/inc scp2/InstallModule_ooo.mk scp2/source sc/qa sc/source sd/inc sd/qa sd/source setup_native/source sfx2/source solenv/gbuild starmath/Library_sm.mk starmath/source svtools/source svx/inc svx/source sw/qa sw/source ucbhelper/source ucb/source unoxml/source uui/source vcl/Library_vcl.mk vcl/Library_vclopengl.mk vcl/Module_vcl.mk vcl/source writerfilter/source xmlhelp/source xmloff/inc xmloff/source
Chris Sherlock
chris.sherlock79 at gmail.com
Tue Apr 15 03:18:37 PDT 2014
Rebased ref, commits from common ancestor:
commit 600dc5ed8213bd802562766487f93df81397f94f
Author: Chris Sherlock <chris.sherlock79 at gmail.com>
Date: Tue Apr 15 19:43:57 2014 +1000
Move alpha.cxx contents into bitmap.cxx
Change-Id: Ia61c3b28012a493ac1099fbc5ffb9f5199b2ae5e
diff --git a/vcl/Library_vcl.mk b/vcl/Library_vcl.mk
index 6851f0c..7c8b3eb 100644
--- a/vcl/Library_vcl.mk
+++ b/vcl/Library_vcl.mk
@@ -239,7 +239,6 @@ $(eval $(call gb_Library_add_exception_objects,vcl,\
vcl/source/outdev/bezier \
vcl/source/outdev/polygon \
vcl/source/outdev/transparent \
- vcl/source/outdev/alpha \
vcl/source/outdev/blend \
vcl/source/outdev/mask \
vcl/source/outdev/bitmap \
diff --git a/vcl/source/outdev/alpha.cxx b/vcl/source/outdev/alpha.cxx
deleted file mode 100644
index 717c5d1..0000000
--- a/vcl/source/outdev/alpha.cxx
+++ /dev/null
@@ -1,222 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*
- * This file is part of the LibreOffice project.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- *
- * This file incorporates work covered by the following license notice:
- *
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed
- * with this work for additional information regarding copyright
- * ownership. The ASF licenses this file to you under the Apache
- * License, Version 2.0 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of
- * the License at http://www.apache.org/licenses/LICENSE-2.0 .
- */
-
-#include <tools/debug.hxx>
-#include <vcl/bitmap.hxx>
-#include <vcl/bitmapex.hxx>
-#include <vcl/window.hxx>
-#include <vcl/metaact.hxx>
-#include <vcl/gdimtf.hxx>
-#include <vcl/virdev.hxx>
-#include <vcl/bmpacc.hxx>
-#include <vcl/outdev.hxx>
-#include <vcl/image.hxx>
-#include <bmpfast.hxx>
-#include <salbmp.hxx>
-#include <salgdi.hxx>
-#include <impbmp.hxx>
-#include <sallayout.hxx>
-#include <image.h>
-#include <outdev.h>
-#include <window.h>
-#include <outdata.hxx>
-#include <basegfx/matrix/b2dhommatrix.hxx>
-#include <basegfx/matrix/b2dhommatrixtools.hxx>
-#include <boost/scoped_array.hpp>
-
-void OutputDevice::ImplDrawAlpha( const Bitmap& rBmp, const AlphaMask& rAlpha,
- const Point& rDestPt, const Size& rDestSize,
- const Point& rSrcPtPixel, const Size& rSrcSizePixel )
-{
- const Point aNullPt;
- Point aOutPt( LogicToPixel( rDestPt ) );
- Size aOutSz( LogicToPixel( rDestSize ) );
- Rectangle aDstRect( aNullPt, GetOutputSizePixel() );
- const bool bHMirr = aOutSz.Width() < 0;
- const bool bVMirr = aOutSz.Height() < 0;
-
- ClipToPaintRegion(aDstRect);
-
- if( bHMirr )
- {
- aOutSz.Width() = -aOutSz.Width();
- aOutPt.X() -= ( aOutSz.Width() - 1L );
- }
-
- if( bVMirr )
- {
- aOutSz.Height() = -aOutSz.Height();
- aOutPt.Y() -= ( aOutSz.Height() - 1L );
- }
-
- if( !aDstRect.Intersection( Rectangle( aOutPt, aOutSz ) ).IsEmpty() )
- {
- bool bNativeAlpha = false;
- static const char* pDisableNative = getenv( "SAL_DISABLE_NATIVE_ALPHA");
- // #i83087# Naturally, system alpha blending cannot work with
- // separate alpha VDev
- bool bTryDirectPaint(!mpAlphaVDev && !pDisableNative && !bHMirr && !bVMirr);
-
-#ifdef WNT
- if(bTryDirectPaint)
- {
- // only paint direct when no scaling and no MapMode, else the
- // more expensive conversions may be done for short-time Bitmap/BitmapEx
- // used for buffering only
- if(!IsMapMode() && rSrcSizePixel.Width() == aOutSz.Width() && rSrcSizePixel.Height() == aOutSz.Height())
- {
- bTryDirectPaint = false;
- }
- }
-#endif
-
- if(bTryDirectPaint)
- {
- Point aRelPt = aOutPt + Point( mnOutOffX, mnOutOffY );
- SalTwoRect aTR = {
- rSrcPtPixel.X(), rSrcPtPixel.Y(),
- rSrcSizePixel.Width(), rSrcSizePixel.Height(),
- aRelPt.X(), aRelPt.Y(),
- aOutSz.Width(), aOutSz.Height()
- };
- SalBitmap* pSalSrcBmp = rBmp.ImplGetImpBitmap()->ImplGetSalBitmap();
- SalBitmap* pSalAlphaBmp = rAlpha.ImplGetImpBitmap()->ImplGetSalBitmap();
- bNativeAlpha = mpGraphics->DrawAlphaBitmap( aTR, *pSalSrcBmp, *pSalAlphaBmp, this );
- }
-
- VirtualDevice* pOldVDev = mpAlphaVDev;
-
- Rectangle aBmpRect( aNullPt, rBmp.GetSizePixel() );
- if( !bNativeAlpha
- && !aBmpRect.Intersection( Rectangle( rSrcPtPixel, rSrcSizePixel ) ).IsEmpty() )
- {
- // The scaling in this code path produces really ugly results - it
- // does the most trivial scaling with no smoothing.
-
- GDIMetaFile* pOldMetaFile = mpMetaFile;
- const bool bOldMap = mbMap;
- mpMetaFile = NULL; // fdo#55044 reset before GetBitmap!
- mbMap = false;
- Bitmap aBmp( GetBitmap( aDstRect.TopLeft(), aDstRect.GetSize() ) );
-
- // #109044# The generated bitmap need not necessarily be
- // of aDstRect dimensions, it's internally clipped to
- // window bounds. Thus, we correct the dest size here,
- // since we later use it (in nDstWidth/Height) for pixel
- // access)
- // #i38887# reading from screen may sometimes fail
- if( aBmp.ImplGetImpBitmap() )
- aDstRect.SetSize( aBmp.GetSizePixel() );
-
- BitmapColor aDstCol;
- const long nSrcWidth = aBmpRect.GetWidth(), nSrcHeight = aBmpRect.GetHeight();
- const long nDstWidth = aDstRect.GetWidth(), nDstHeight = aDstRect.GetHeight();
- const long nOutWidth = aOutSz.Width(), nOutHeight = aOutSz.Height();
- // calculate offset in original bitmap
- // in RTL case this is a little more complicated since the contents of the
- // bitmap is not mirrored (it never is), however the paint region and bmp region
- // are in mirrored coordinates, so the intersection of (aOutPt,aOutSz) with these
- // is content wise somewhere else and needs to take mirroring into account
- const long nOffX = IsRTLEnabled()
- ? aOutSz.Width() - aDstRect.GetWidth() - (aDstRect.Left() - aOutPt.X())
- : aDstRect.Left() - aOutPt.X(),
- nOffY = aDstRect.Top() - aOutPt.Y();
- long nX, nOutX, nY, nOutY;
- long nMirrOffX = 0;
- long nMirrOffY = 0;
- boost::scoped_array<long> pMapX(new long[ nDstWidth ]);
- boost::scoped_array<long> pMapY(new long[ nDstHeight ]);
-
- // create horizontal mapping table
- if( bHMirr )
- nMirrOffX = ( aBmpRect.Left() << 1 ) + nSrcWidth - 1;
-
- for( nX = 0L, nOutX = nOffX; nX < nDstWidth; nX++, nOutX++ )
- {
- pMapX[ nX ] = aBmpRect.Left() + nOutX * nSrcWidth / nOutWidth;
- if( bHMirr )
- pMapX[ nX ] = nMirrOffX - pMapX[ nX ];
- }
-
- // create vertical mapping table
- if( bVMirr )
- nMirrOffY = ( aBmpRect.Top() << 1 ) + nSrcHeight - 1;
-
- for( nY = 0L, nOutY = nOffY; nY < nDstHeight; nY++, nOutY++ )
- {
- pMapY[ nY ] = aBmpRect.Top() + nOutY * nSrcHeight / nOutHeight;
-
- if( bVMirr )
- pMapY[ nY ] = nMirrOffY - pMapY[ nY ];
- }
-
- BitmapReadAccess* pP = ( (Bitmap&) rBmp ).AcquireReadAccess();
- BitmapReadAccess* pA = ( (AlphaMask&) rAlpha ).AcquireReadAccess();
-
- DBG_ASSERT( pA->GetScanlineFormat() == BMP_FORMAT_8BIT_PAL ||
- pA->GetScanlineFormat() == BMP_FORMAT_8BIT_TC_MASK,
- "OutputDevice::ImplDrawAlpha(): non-8bit alpha no longer supported!" );
-
- // #i38887# reading from screen may sometimes fail
- if( aBmp.ImplGetImpBitmap() )
- {
- Bitmap aTmp;
-
- if( mpAlphaVDev )
- {
- aTmp = ImplBlendWithAlpha(
- aBmp,pP,pA,
- aDstRect,
- nOffY,nDstHeight,
- nOffX,nDstWidth,
- pMapX.get(),pMapY.get() );
- }
- else
- {
- aTmp = ImplBlend(
- aBmp,pP,pA,
- nOffY,nDstHeight,
- nOffX,nDstWidth,
- aBmpRect,aOutSz,
- bHMirr,bVMirr,
- pMapX.get(),pMapY.get() );
- }
-
- // #110958# Disable alpha VDev, we're doing the necessary
- // stuff explicitly furher below
- if( mpAlphaVDev )
- mpAlphaVDev = NULL;
-
- DrawBitmap( aDstRect.TopLeft(),
- aTmp );
-
- // #110958# Enable alpha VDev again
- mpAlphaVDev = pOldVDev;
- }
-
- ( (Bitmap&) rBmp ).ReleaseAccess( pP );
- ( (AlphaMask&) rAlpha ).ReleaseAccess( pA );
-
- mbMap = bOldMap;
- mpMetaFile = pOldMetaFile;
- }
- }
-}
-
-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/source/outdev/bitmap.cxx b/vcl/source/outdev/bitmap.cxx
index d409ac9..80b7c4e 100644
--- a/vcl/source/outdev/bitmap.cxx
+++ b/vcl/source/outdev/bitmap.cxx
@@ -993,4 +993,183 @@ BitmapEx OutputDevice::GetBitmapEx( const Point& rSrcPt, const Size& rSize ) con
return GetBitmap( rSrcPt, rSize );
}
+void OutputDevice::ImplDrawAlpha( const Bitmap& rBmp, const AlphaMask& rAlpha,
+ const Point& rDestPt, const Size& rDestSize,
+ const Point& rSrcPtPixel, const Size& rSrcSizePixel )
+{
+ const Point aNullPt;
+ Point aOutPt( LogicToPixel( rDestPt ) );
+ Size aOutSz( LogicToPixel( rDestSize ) );
+ Rectangle aDstRect( aNullPt, GetOutputSizePixel() );
+ const bool bHMirr = aOutSz.Width() < 0;
+ const bool bVMirr = aOutSz.Height() < 0;
+
+ ClipToPaintRegion(aDstRect);
+
+ if( bHMirr )
+ {
+ aOutSz.Width() = -aOutSz.Width();
+ aOutPt.X() -= ( aOutSz.Width() - 1L );
+ }
+
+ if( bVMirr )
+ {
+ aOutSz.Height() = -aOutSz.Height();
+ aOutPt.Y() -= ( aOutSz.Height() - 1L );
+ }
+
+ if( !aDstRect.Intersection( Rectangle( aOutPt, aOutSz ) ).IsEmpty() )
+ {
+ bool bNativeAlpha = false;
+ static const char* pDisableNative = getenv( "SAL_DISABLE_NATIVE_ALPHA");
+ // #i83087# Naturally, system alpha blending cannot work with
+ // separate alpha VDev
+ bool bTryDirectPaint(!mpAlphaVDev && !pDisableNative && !bHMirr && !bVMirr);
+
+#ifdef WNT
+ if(bTryDirectPaint)
+ {
+ // only paint direct when no scaling and no MapMode, else the
+ // more expensive conversions may be done for short-time Bitmap/BitmapEx
+ // used for buffering only
+ if(!IsMapMode() && rSrcSizePixel.Width() == aOutSz.Width() && rSrcSizePixel.Height() == aOutSz.Height())
+ {
+ bTryDirectPaint = false;
+ }
+ }
+#endif
+
+ if(bTryDirectPaint)
+ {
+ Point aRelPt = aOutPt + Point( mnOutOffX, mnOutOffY );
+ SalTwoRect aTR = {
+ rSrcPtPixel.X(), rSrcPtPixel.Y(),
+ rSrcSizePixel.Width(), rSrcSizePixel.Height(),
+ aRelPt.X(), aRelPt.Y(),
+ aOutSz.Width(), aOutSz.Height()
+ };
+ SalBitmap* pSalSrcBmp = rBmp.ImplGetImpBitmap()->ImplGetSalBitmap();
+ SalBitmap* pSalAlphaBmp = rAlpha.ImplGetImpBitmap()->ImplGetSalBitmap();
+ bNativeAlpha = mpGraphics->DrawAlphaBitmap( aTR, *pSalSrcBmp, *pSalAlphaBmp, this );
+ }
+
+ VirtualDevice* pOldVDev = mpAlphaVDev;
+
+ Rectangle aBmpRect( aNullPt, rBmp.GetSizePixel() );
+ if( !bNativeAlpha
+ && !aBmpRect.Intersection( Rectangle( rSrcPtPixel, rSrcSizePixel ) ).IsEmpty() )
+ {
+ // The scaling in this code path produces really ugly results - it
+ // does the most trivial scaling with no smoothing.
+
+ GDIMetaFile* pOldMetaFile = mpMetaFile;
+ const bool bOldMap = mbMap;
+ mpMetaFile = NULL; // fdo#55044 reset before GetBitmap!
+ mbMap = false;
+ Bitmap aBmp( GetBitmap( aDstRect.TopLeft(), aDstRect.GetSize() ) );
+
+ // #109044# The generated bitmap need not necessarily be
+ // of aDstRect dimensions, it's internally clipped to
+ // window bounds. Thus, we correct the dest size here,
+ // since we later use it (in nDstWidth/Height) for pixel
+ // access)
+ // #i38887# reading from screen may sometimes fail
+ if( aBmp.ImplGetImpBitmap() )
+ aDstRect.SetSize( aBmp.GetSizePixel() );
+
+ BitmapColor aDstCol;
+ const long nSrcWidth = aBmpRect.GetWidth(), nSrcHeight = aBmpRect.GetHeight();
+ const long nDstWidth = aDstRect.GetWidth(), nDstHeight = aDstRect.GetHeight();
+ const long nOutWidth = aOutSz.Width(), nOutHeight = aOutSz.Height();
+ // calculate offset in original bitmap
+ // in RTL case this is a little more complicated since the contents of the
+ // bitmap is not mirrored (it never is), however the paint region and bmp region
+ // are in mirrored coordinates, so the intersection of (aOutPt,aOutSz) with these
+ // is content wise somewhere else and needs to take mirroring into account
+ const long nOffX = IsRTLEnabled()
+ ? aOutSz.Width() - aDstRect.GetWidth() - (aDstRect.Left() - aOutPt.X())
+ : aDstRect.Left() - aOutPt.X(),
+ nOffY = aDstRect.Top() - aOutPt.Y();
+ long nX, nOutX, nY, nOutY;
+ long nMirrOffX = 0;
+ long nMirrOffY = 0;
+ boost::scoped_array<long> pMapX(new long[ nDstWidth ]);
+ boost::scoped_array<long> pMapY(new long[ nDstHeight ]);
+
+ // create horizontal mapping table
+ if( bHMirr )
+ nMirrOffX = ( aBmpRect.Left() << 1 ) + nSrcWidth - 1;
+
+ for( nX = 0L, nOutX = nOffX; nX < nDstWidth; nX++, nOutX++ )
+ {
+ pMapX[ nX ] = aBmpRect.Left() + nOutX * nSrcWidth / nOutWidth;
+ if( bHMirr )
+ pMapX[ nX ] = nMirrOffX - pMapX[ nX ];
+ }
+
+ // create vertical mapping table
+ if( bVMirr )
+ nMirrOffY = ( aBmpRect.Top() << 1 ) + nSrcHeight - 1;
+
+ for( nY = 0L, nOutY = nOffY; nY < nDstHeight; nY++, nOutY++ )
+ {
+ pMapY[ nY ] = aBmpRect.Top() + nOutY * nSrcHeight / nOutHeight;
+
+ if( bVMirr )
+ pMapY[ nY ] = nMirrOffY - pMapY[ nY ];
+ }
+
+ BitmapReadAccess* pP = ( (Bitmap&) rBmp ).AcquireReadAccess();
+ BitmapReadAccess* pA = ( (AlphaMask&) rAlpha ).AcquireReadAccess();
+
+ DBG_ASSERT( pA->GetScanlineFormat() == BMP_FORMAT_8BIT_PAL ||
+ pA->GetScanlineFormat() == BMP_FORMAT_8BIT_TC_MASK,
+ "OutputDevice::ImplDrawAlpha(): non-8bit alpha no longer supported!" );
+
+ // #i38887# reading from screen may sometimes fail
+ if( aBmp.ImplGetImpBitmap() )
+ {
+ Bitmap aTmp;
+
+ if( mpAlphaVDev )
+ {
+ aTmp = ImplBlendWithAlpha(
+ aBmp,pP,pA,
+ aDstRect,
+ nOffY,nDstHeight,
+ nOffX,nDstWidth,
+ pMapX.get(),pMapY.get() );
+ }
+ else
+ {
+ aTmp = ImplBlend(
+ aBmp,pP,pA,
+ nOffY,nDstHeight,
+ nOffX,nDstWidth,
+ aBmpRect,aOutSz,
+ bHMirr,bVMirr,
+ pMapX.get(),pMapY.get() );
+ }
+
+ // #110958# Disable alpha VDev, we're doing the necessary
+ // stuff explicitly furher below
+ if( mpAlphaVDev )
+ mpAlphaVDev = NULL;
+
+ DrawBitmap( aDstRect.TopLeft(),
+ aTmp );
+
+ // #110958# Enable alpha VDev again
+ mpAlphaVDev = pOldVDev;
+ }
+
+ ( (Bitmap&) rBmp ).ReleaseAccess( pP );
+ ( (AlphaMask&) rAlpha ).ReleaseAccess( pA );
+
+ mbMap = bOldMap;
+ mpMetaFile = pOldMetaFile;
+ }
+ }
+}
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
commit 3bf6e6a719e3549c5bba28711f7e98ba5ec3227a
Author: Chris Sherlock <chris.sherlock79 at gmail.com>
Date: Tue Apr 15 01:06:48 2014 +1000
Split outdev5.cxx and outdev6.cxx
outdev5.cxx deals with curved shapes, so renamed to curvedshapes.cxx
Moved polygon functions to polygon.cxx, transparency functions to
transparent.cxx, a few miscellaneous functions to outdev.cxx and as the
rest of the functions are wallpaper functions then renamed outdev6.cxx
to wallpaper.cxx
Change-Id: I62a0b66d4d66740fb5f70ecb558db1ad3bf76eb5
diff --git a/vcl/Library_vcl.mk b/vcl/Library_vcl.mk
index b1fd7e8..6851f0c 100644
--- a/vcl/Library_vcl.mk
+++ b/vcl/Library_vcl.mk
@@ -234,6 +234,7 @@ $(eval $(call gb_Library_add_exception_objects,vcl,\
vcl/source/gdi/metric \
vcl/source/gdi/octree \
vcl/source/gdi/oldprintadaptor \
+ vcl/source/outdev/outdev \
vcl/source/outdev/tworect \
vcl/source/outdev/bezier \
vcl/source/outdev/polygon \
@@ -250,9 +251,8 @@ $(eval $(call gb_Library_add_exception_objects,vcl,\
vcl/source/outdev/polyline \
vcl/source/outdev/hatch \
vcl/source/outdev/gradient \
- vcl/source/outdev/outdev5 \
- vcl/source/outdev/outdev6 \
- vcl/source/outdev/outdev \
+ vcl/source/outdev/curvedshapes \
+ vcl/source/outdev/wallpaper \
vcl/source/outdev/outdevnative \
vcl/source/outdev/outmap \
vcl/source/gdi/pdfextoutdevdata \
diff --git a/vcl/source/outdev/outdev5.cxx b/vcl/source/outdev/curvedshapes.cxx
similarity index 100%
rename from vcl/source/outdev/outdev5.cxx
rename to vcl/source/outdev/curvedshapes.cxx
diff --git a/vcl/source/outdev/outdev.cxx b/vcl/source/outdev/outdev.cxx
index 25d8992..cba7542 100644
--- a/vcl/source/outdev/outdev.cxx
+++ b/vcl/source/outdev/outdev.cxx
@@ -1576,4 +1576,122 @@ css::uno::Reference< css::rendering::XCanvas > OutputDevice::GetCanvas() const
return xCanvas;
}
+void OutputDevice::Erase()
+{
+ if ( !IsDeviceOutputNecessary() || ImplIsRecordLayout() )
+ return;
+
+ bool bNativeOK = false;
+
+ if( meOutDevType == OUTDEV_WINDOW )
+ {
+ Window* pWindow = static_cast<Window*>(this);
+ ControlPart aCtrlPart = pWindow->ImplGetWindowImpl()->mnNativeBackground;
+ if( aCtrlPart != 0 && ! pWindow->IsControlBackground() )
+ {
+ ImplControlValue aControlValue;
+ Point aGcc3WorkaroundTemporary;
+ Rectangle aCtrlRegion( aGcc3WorkaroundTemporary, GetOutputSizePixel() );
+ ControlState nState = 0;
+
+ if( pWindow->IsEnabled() ) nState |= CTRL_STATE_ENABLED;
+ bNativeOK = pWindow->DrawNativeControl( CTRL_WINDOW_BACKGROUND, aCtrlPart, aCtrlRegion,
+ nState, aControlValue, OUString() );
+ }
+ }
+
+ if ( mbBackground && ! bNativeOK )
+ {
+ RasterOp eRasterOp = GetRasterOp();
+ if ( eRasterOp != ROP_OVERPAINT )
+ SetRasterOp( ROP_OVERPAINT );
+ ImplDrawWallpaper( 0, 0, mnOutWidth, mnOutHeight, maBackground );
+ if ( eRasterOp != ROP_OVERPAINT )
+ SetRasterOp( eRasterOp );
+ }
+
+ if( mpAlphaVDev )
+ mpAlphaVDev->Erase();
+}
+
+bool OutputDevice::DrawEPS( const Point& rPoint, const Size& rSize,
+ const GfxLink& rGfxLink, GDIMetaFile* pSubst )
+{
+ bool bDrawn(true);
+
+ if ( mpMetaFile )
+ {
+ GDIMetaFile aSubst;
+
+ if( pSubst )
+ aSubst = *pSubst;
+
+ mpMetaFile->AddAction( new MetaEPSAction( rPoint, rSize, rGfxLink, aSubst ) );
+ }
+
+ if ( !IsDeviceOutputNecessary() || ImplIsRecordLayout() )
+ return bDrawn;
+
+ if( mbOutputClipped )
+ return bDrawn;
+
+ Rectangle aRect( ImplLogicToDevicePixel( Rectangle( rPoint, rSize ) ) );
+
+ if( !aRect.IsEmpty() )
+ {
+ // draw the real EPS graphics
+ if( rGfxLink.GetData() && rGfxLink.GetDataSize() )
+ {
+ if( !mpGraphics && !ImplGetGraphics() )
+ return bDrawn;
+
+ if( mbInitClipRegion )
+ ImplInitClipRegion();
+
+ aRect.Justify();
+ bDrawn = mpGraphics->DrawEPS( aRect.Left(), aRect.Top(), aRect.GetWidth(), aRect.GetHeight(),
+ (sal_uInt8*) rGfxLink.GetData(), rGfxLink.GetDataSize(), this );
+ }
+
+ // else draw the substitution graphics
+ if( !bDrawn && pSubst )
+ {
+ GDIMetaFile* pOldMetaFile = mpMetaFile;
+
+ mpMetaFile = NULL;
+ Graphic( *pSubst ).Draw( this, rPoint, rSize );
+ mpMetaFile = pOldMetaFile;
+ }
+ }
+
+ if( mpAlphaVDev )
+ mpAlphaVDev->DrawEPS( rPoint, rSize, rGfxLink, pSubst );
+
+ return bDrawn;
+}
+
+void OutputDevice::DrawCheckered(const Point& rPos, const Size& rSize, sal_uInt32 nLen, Color aStart, Color aEnd)
+{
+ const sal_uInt32 nMaxX(rPos.X() + rSize.Width());
+ const sal_uInt32 nMaxY(rPos.Y() + rSize.Height());
+
+ Push(PUSH_LINECOLOR|PUSH_FILLCOLOR);
+ SetLineColor();
+
+ for(sal_uInt32 x(0), nX(rPos.X()); nX < nMaxX; x++, nX += nLen)
+ {
+ const sal_uInt32 nRight(std::min(nMaxX, nX + nLen));
+
+ for(sal_uInt32 y(0), nY(rPos.Y()); nY < nMaxY; y++, nY += nLen)
+ {
+ const sal_uInt32 nBottom(std::min(nMaxY, nY + nLen));
+
+ SetFillColor((x & 0x0001) ^ (y & 0x0001) ? aStart : aEnd);
+ DrawRect(Rectangle(nX, nY, nRight, nBottom));
+ }
+ }
+
+ Pop();
+}
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/source/outdev/outdev6.cxx b/vcl/source/outdev/outdev6.cxx
deleted file mode 100644
index b4de152..0000000
--- a/vcl/source/outdev/outdev6.cxx
+++ /dev/null
@@ -1,1196 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*
- * This file is part of the LibreOffice project.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- *
- * This file incorporates work covered by the following license notice:
- *
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed
- * with this work for additional information regarding copyright
- * ownership. The ASF licenses this file to you under the Apache
- * License, Version 2.0 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of
- * the License at http://www.apache.org/licenses/LICENSE-2.0 .
- */
-
-#include <tools/debug.hxx>
-#include <vcl/outdev.hxx>
-#include <vcl/virdev.hxx>
-#include <vcl/bmpacc.hxx>
-#include <vcl/metaact.hxx>
-#include <vcl/gdimtf.hxx>
-#include <vcl/svapp.hxx>
-#include <vcl/wrkwin.hxx>
-#include <vcl/graph.hxx>
-
-#include <wall2.hxx>
-#include <salgdi.hxx>
-#include <window.h>
-#include <svdata.hxx>
-#include <outdev.h>
-
-#include <com/sun/star/uno/Sequence.hxx>
-
-#include <basegfx/vector/b2dvector.hxx>
-#include <basegfx/polygon/b2dpolypolygon.hxx>
-#include <basegfx/polygon/b2dpolygon.hxx>
-#include <basegfx/matrix/b2dhommatrix.hxx>
-
-#include <math.h>
-#include <boost/scoped_ptr.hpp>
-
-namespace {
-
-/**
- * Perform a safe approximation of a polygon from double-precision
- * coordinates to integer coordinates, to ensure that it has at least 2
- * pixels in both X and Y directions.
- */
-Polygon toPolygon( const basegfx::B2DPolygon& rPoly )
-{
- basegfx::B2DRange aRange = rPoly.getB2DRange();
- double fW = aRange.getWidth(), fH = aRange.getHeight();
- if (0.0 < fW && 0.0 < fH && (fW <= 1.0 || fH <= 1.0))
- {
- // This polygon not empty but is too small to display. Approximate it
- // with a rectangle large enough to be displayed.
- double nX = aRange.getMinX(), nY = aRange.getMinY();
- double nW = std::max<double>(1.0, rtl::math::round(fW));
- double nH = std::max<double>(1.0, rtl::math::round(fH));
-
- Polygon aTarget;
- aTarget.Insert(0, Point(nX, nY));
- aTarget.Insert(1, Point(nX+nW, nY));
- aTarget.Insert(2, Point(nX+nW, nY+nH));
- aTarget.Insert(3, Point(nX, nY+nH));
- aTarget.Insert(4, Point(nX, nY));
- return aTarget;
- }
- return Polygon(rPoly);
-}
-
-PolyPolygon toPolyPolygon( const basegfx::B2DPolyPolygon& rPolyPoly )
-{
- PolyPolygon aTarget;
- for (sal_uInt32 i = 0; i < rPolyPoly.count(); ++i)
- aTarget.Insert(toPolygon(rPolyPoly.getB2DPolygon(i)));
-
- return aTarget;
-}
-
-}
-
-void OutputDevice::DrawGrid( const Rectangle& rRect, const Size& rDist, sal_uLong nFlags )
-{
-
- Rectangle aDstRect( PixelToLogic( Point() ), GetOutputSize() );
- aDstRect.Intersection( rRect );
-
- if( aDstRect.IsEmpty() || ImplIsRecordLayout() )
- return;
-
- if( !mpGraphics && !ImplGetGraphics() )
- return;
-
- if( mbInitClipRegion )
- ImplInitClipRegion();
-
- if( mbOutputClipped )
- return;
-
- const long nDistX = std::max( rDist.Width(), 1L );
- const long nDistY = std::max( rDist.Height(), 1L );
- long nX = ( rRect.Left() >= aDstRect.Left() ) ? rRect.Left() : ( rRect.Left() + ( ( aDstRect.Left() - rRect.Left() ) / nDistX ) * nDistX );
- long nY = ( rRect.Top() >= aDstRect.Top() ) ? rRect.Top() : ( rRect.Top() + ( ( aDstRect.Top() - rRect.Top() ) / nDistY ) * nDistY );
- const long nRight = aDstRect.Right();
- const long nBottom = aDstRect.Bottom();
- const long nStartX = ImplLogicXToDevicePixel( nX );
- const long nEndX = ImplLogicXToDevicePixel( nRight );
- const long nStartY = ImplLogicYToDevicePixel( nY );
- const long nEndY = ImplLogicYToDevicePixel( nBottom );
- long nHorzCount = 0L;
- long nVertCount = 0L;
-
- ::com::sun::star::uno::Sequence< sal_Int32 > aVertBuf;
- ::com::sun::star::uno::Sequence< sal_Int32 > aHorzBuf;
-
- if( ( nFlags & GRID_DOTS ) || ( nFlags & GRID_HORZLINES ) )
- {
- aVertBuf.realloc( aDstRect.GetHeight() / nDistY + 2L );
- aVertBuf[ nVertCount++ ] = nStartY;
- while( ( nY += nDistY ) <= nBottom )
- aVertBuf[ nVertCount++ ] = ImplLogicYToDevicePixel( nY );
- }
-
- if( ( nFlags & GRID_DOTS ) || ( nFlags & GRID_VERTLINES ) )
- {
- aHorzBuf.realloc( aDstRect.GetWidth() / nDistX + 2L );
- aHorzBuf[ nHorzCount++ ] = nStartX;
- while( ( nX += nDistX ) <= nRight )
- aHorzBuf[ nHorzCount++ ] = ImplLogicXToDevicePixel( nX );
- }
-
- if( mbInitLineColor )
- ImplInitLineColor();
-
- if( mbInitFillColor )
- ImplInitFillColor();
-
- const bool bOldMap = mbMap;
- EnableMapMode( false );
-
- if( nFlags & GRID_DOTS )
- {
- for( long i = 0L; i < nVertCount; i++ )
- for( long j = 0L, Y = aVertBuf[ i ]; j < nHorzCount; j++ )
- mpGraphics->DrawPixel( aHorzBuf[ j ], Y, this );
- }
- else
- {
- if( nFlags & GRID_HORZLINES )
- {
- for( long i = 0L; i < nVertCount; i++ )
- {
- nY = aVertBuf[ i ];
- mpGraphics->DrawLine( nStartX, nY, nEndX, nY, this );
- }
- }
-
- if( nFlags & GRID_VERTLINES )
- {
- for( long i = 0L; i < nHorzCount; i++ )
- {
- nX = aHorzBuf[ i ];
- mpGraphics->DrawLine( nX, nStartY, nX, nEndY, this );
- }
- }
- }
-
- EnableMapMode( bOldMap );
-
- if( mpAlphaVDev )
- mpAlphaVDev->DrawGrid( rRect, rDist, nFlags );
-}
-
-// Caution: This method is nearly the same as
-// void OutputDevice::DrawPolyPolygon( const basegfx::B2DPolyPolygon& rB2DPolyPoly )
-// so when changes are made here do not forget to make changes there, too
-
-void OutputDevice::DrawTransparent( const basegfx::B2DPolyPolygon& rB2DPolyPoly, double fTransparency)
-{
- // AW: Do NOT paint empty PolyPolygons
- if(!rB2DPolyPoly.count())
- return;
-
- // we need a graphics
- if( !mpGraphics )
- if( !ImplGetGraphics() )
- return;
-
- if( mbInitClipRegion )
- ImplInitClipRegion();
- if( mbOutputClipped )
- return;
-
- if( mbInitLineColor )
- ImplInitLineColor();
- if( mbInitFillColor )
- ImplInitFillColor();
-
- if((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW)
- && mpGraphics->supportsOperation(OutDevSupport_B2DDraw)
- && ROP_OVERPAINT == GetRasterOp() )
- {
- // b2dpolygon support not implemented yet on non-UNX platforms
- const ::basegfx::B2DHomMatrix aTransform = ImplGetDeviceTransformation();
- basegfx::B2DPolyPolygon aB2DPolyPolygon(rB2DPolyPoly);
-
- // transform the polygon into device space and ensure it is closed
- aB2DPolyPolygon.transform( aTransform );
- aB2DPolyPolygon.setClosed( true );
-
- bool bDrawnOk = true;
- if( IsFillColor() )
- bDrawnOk = mpGraphics->DrawPolyPolygon( aB2DPolyPolygon, fTransparency, this );
- if( bDrawnOk && IsLineColor() )
- {
- const basegfx::B2DVector aHairlineWidth(1,1);
- const int nPolyCount = aB2DPolyPolygon.count();
- for( int nPolyIdx = 0; nPolyIdx < nPolyCount; ++nPolyIdx )
- {
- const ::basegfx::B2DPolygon aOnePoly = aB2DPolyPolygon.getB2DPolygon( nPolyIdx );
- mpGraphics->DrawPolyLine( aOnePoly, fTransparency, aHairlineWidth, ::basegfx::B2DLINEJOIN_NONE, com::sun::star::drawing::LineCap_BUTT, this );
- }
- }
-
- if( bDrawnOk )
- {
- if( mpMetaFile )
- mpMetaFile->AddAction( new MetaTransparentAction( PolyPolygon( rB2DPolyPoly ), static_cast< sal_uInt16 >(fTransparency * 100.0)));
- return;
- }
- }
-
- // fallback to old polygon drawing if needed
- DrawTransparent(toPolyPolygon(rB2DPolyPoly), static_cast<sal_uInt16>(fTransparency * 100.0));
-}
-
-void OutputDevice::DrawInvisiblePolygon( const PolyPolygon& rPolyPoly )
-{
- // short circuit if the polygon border is invisible too
- if( !mbLineColor )
- return;
-
- // we assume that the border is NOT to be drawn transparently???
- Push( PUSH_FILLCOLOR );
- SetFillColor();
- DrawPolyPolygon( rPolyPoly );
- Pop();
-}
-
-bool OutputDevice::DrawTransparentNatively ( const PolyPolygon& rPolyPoly,
- sal_uInt16 nTransparencePercent )
-{
- bool bDrawn = false;
-
- // debug helper:
- static const char* pDisableNative = getenv( "SAL_DISABLE_NATIVE_ALPHA");
-
- if( !pDisableNative
- && mpGraphics->supportsOperation( OutDevSupport_B2DDraw )
-#if defined UNX && ! defined MACOSX && ! defined IOS
- && GetBitCount() > 8
-#endif
-#ifdef WIN32
- // workaround bad dithering on remote displaying when using GDI+ with toolbar button highlighting
- && !rPolyPoly.IsRect()
-#endif
- )
- {
- // prepare the graphics device
- if( mbInitClipRegion )
- ImplInitClipRegion();
- if( mbOutputClipped )
- return false;
- if( mbInitLineColor )
- ImplInitLineColor();
- if( mbInitFillColor )
- ImplInitFillColor();
-
- // get the polygon in device coordinates
- basegfx::B2DPolyPolygon aB2DPolyPolygon( rPolyPoly.getB2DPolyPolygon() );
- const ::basegfx::B2DHomMatrix aTransform = ImplGetDeviceTransformation();
- aB2DPolyPolygon.transform( aTransform );
-
- const double fTransparency = 0.01 * nTransparencePercent;
- if( mbFillColor )
- {
- // #i121591#
- // CAUTION: Only non printing (pixel-renderer) VCL commands from OutputDevices
- // should be used when printing. Normally this is avoided by the printer being
- // non-AAed and thus e.g. on WIN GdiPlus calls are not used. It may be necessary
- // to figure out a way of moving this code to it's own function that is
- // overriden by the Print class, which will mean we deliberately override the
- // functionality and we use the fallback some lines below (which is not very good,
- // though. For now, WinSalGraphics::drawPolyPolygon will detect printer usage and
- // correct the wrong mapping (see there for details)
- bDrawn = mpGraphics->DrawPolyPolygon( aB2DPolyPolygon, fTransparency, this );
- }
-
- if( mbLineColor )
- {
- // disable the fill color for now
- mpGraphics->SetFillColor();
- // draw the border line
- const basegfx::B2DVector aLineWidths( 1, 1 );
- const int nPolyCount = aB2DPolyPolygon.count();
- for( int nPolyIdx = 0; nPolyIdx < nPolyCount; ++nPolyIdx )
- {
- const ::basegfx::B2DPolygon& rPolygon = aB2DPolyPolygon.getB2DPolygon( nPolyIdx );
- bDrawn = mpGraphics->DrawPolyLine( rPolygon, fTransparency, aLineWidths, ::basegfx::B2DLINEJOIN_NONE, com::sun::star::drawing::LineCap_BUTT, this );
- }
- // prepare to restore the fill color
- mbInitFillColor = mbFillColor;
- }
- }
-
- return bDrawn;
-}
-
-void OutputDevice::EmulateDrawTransparent ( const PolyPolygon& rPolyPoly,
- sal_uInt16 nTransparencePercent )
-{
- // debug helper:
- static const char* pDisableNative = getenv( "SAL_DISABLE_NATIVE_ALPHA");
-
- // #110958# Disable alpha VDev, we perform the necessary
- VirtualDevice* pOldAlphaVDev = mpAlphaVDev;
-
- // operation explicitly further below.
- if( mpAlphaVDev )
- mpAlphaVDev = NULL;
-
- GDIMetaFile* pOldMetaFile = mpMetaFile;
- mpMetaFile = NULL;
-
- PolyPolygon aPolyPoly( LogicToPixel( rPolyPoly ) );
- Rectangle aPolyRect( aPolyPoly.GetBoundRect() );
- Point aPoint;
- Rectangle aDstRect( aPoint, GetOutputSizePixel() );
-
- aDstRect.Intersection( aPolyRect );
-
- ClipToPaintRegion( aDstRect );
-
- if( !aDstRect.IsEmpty() )
- {
- bool bDrawn = false;
-
- // #i66849# Added fast path for exactly rectangular
- // polygons
- // #i83087# Naturally, system alpha blending cannot
- // work with separate alpha VDev
- if( !mpAlphaVDev && !pDisableNative && aPolyPoly.IsRect() )
- {
- // setup Graphics only here (other cases delegate
- // to basic OutDev methods)
- if ( mbInitClipRegion )
- ImplInitClipRegion();
- if ( mbInitLineColor )
- ImplInitLineColor();
- if ( mbInitFillColor )
- ImplInitFillColor();
-
- Rectangle aLogicPolyRect( rPolyPoly.GetBoundRect() );
- Rectangle aPixelRect( ImplLogicToDevicePixel( aLogicPolyRect ) );
-
- if( !mbOutputClipped )
- {
- bDrawn = mpGraphics->DrawAlphaRect(
- aPixelRect.Left(), aPixelRect.Top(),
- // #i98405# use methods with small g, else one pixel too much will be painted.
- // This is because the source is a polygon which when painted would not paint
- // the rightmost and lowest pixel line(s), so use one pixel less for the
- // rectangle, too.
- aPixelRect.getWidth(), aPixelRect.getHeight(),
- sal::static_int_cast<sal_uInt8>(nTransparencePercent),
- this );
- }
- else
- bDrawn = true;
- }
-
- if( !bDrawn )
- {
- VirtualDevice aVDev( *this, 1 );
- const Size aDstSz( aDstRect.GetSize() );
- const sal_uInt8 cTrans = (sal_uInt8) MinMax( FRound( nTransparencePercent * 2.55 ), 0, 255 );
-
- if( aDstRect.Left() || aDstRect.Top() )
- aPolyPoly.Move( -aDstRect.Left(), -aDstRect.Top() );
-
- if( aVDev.SetOutputSizePixel( aDstSz ) )
- {
- const bool bOldMap = mbMap;
-
- EnableMapMode( false );
-
- aVDev.SetLineColor( COL_BLACK );
- aVDev.SetFillColor( COL_BLACK );
- aVDev.DrawPolyPolygon( aPolyPoly );
-
- Bitmap aPaint( GetBitmap( aDstRect.TopLeft(), aDstSz ) );
- Bitmap aPolyMask( aVDev.GetBitmap( Point(), aDstSz ) );
-
- // #107766# check for non-empty bitmaps before accessing them
- if( !!aPaint && !!aPolyMask )
- {
- BitmapWriteAccess* pW = aPaint.AcquireWriteAccess();
- BitmapReadAccess* pR = aPolyMask.AcquireReadAccess();
-
- if( pW && pR )
- {
- BitmapColor aPixCol;
- const BitmapColor aFillCol( GetFillColor() );
- const BitmapColor aWhite( pR->GetBestMatchingColor( Color( COL_WHITE ) ) );
- const BitmapColor aBlack( pR->GetBestMatchingColor( Color( COL_BLACK ) ) );
- const long nWidth = pW->Width(), nHeight = pW->Height();
- const long nR = aFillCol.GetRed(), nG = aFillCol.GetGreen(), nB = aFillCol.GetBlue();
- long nX, nY;
-
- if( aPaint.GetBitCount() <= 8 )
- {
- const BitmapPalette& rPal = pW->GetPalette();
- const sal_uInt16 nCount = rPal.GetEntryCount();
- BitmapColor* pMap = (BitmapColor*) new sal_uInt8[ nCount * sizeof( BitmapColor ) ];
-
- for( sal_uInt16 i = 0; i < nCount; i++ )
- {
- BitmapColor aCol( rPal[ i ] );
- pMap[ i ] = BitmapColor( (sal_uInt8) rPal.GetBestIndex( aCol.Merge( aFillCol, cTrans ) ) );
- }
-
- if( pR->GetScanlineFormat() == BMP_FORMAT_1BIT_MSB_PAL &&
- pW->GetScanlineFormat() == BMP_FORMAT_8BIT_PAL )
- {
- const sal_uInt8 cBlack = aBlack.GetIndex();
-
- for( nY = 0; nY < nHeight; nY++ )
- {
- Scanline pWScan = pW->GetScanline( nY );
- Scanline pRScan = pR->GetScanline( nY );
- sal_uInt8 cBit = 128;
-
- for( nX = 0; nX < nWidth; nX++, cBit >>= 1, pWScan++ )
- {
- if( !cBit )
- cBit = 128, pRScan++;
-
- if( ( *pRScan & cBit ) == cBlack )
- *pWScan = (sal_uInt8) pMap[ *pWScan ].GetIndex();
- }
- }
- }
- else
- {
- for( nY = 0; nY < nHeight; nY++ )
- for( nX = 0; nX < nWidth; nX++ )
- if( pR->GetPixel( nY, nX ) == aBlack )
- pW->SetPixel( nY, nX, pMap[ pW->GetPixel( nY, nX ).GetIndex() ] );
- }
-
- delete[] (sal_uInt8*) pMap;
- }
- else
- {
- if( pR->GetScanlineFormat() == BMP_FORMAT_1BIT_MSB_PAL &&
- pW->GetScanlineFormat() == BMP_FORMAT_24BIT_TC_BGR )
- {
- const sal_uInt8 cBlack = aBlack.GetIndex();
-
- for( nY = 0; nY < nHeight; nY++ )
- {
- Scanline pWScan = pW->GetScanline( nY );
- Scanline pRScan = pR->GetScanline( nY );
- sal_uInt8 cBit = 128;
-
- for( nX = 0; nX < nWidth; nX++, cBit >>= 1, pWScan += 3 )
- {
- if( !cBit )
- cBit = 128, pRScan++;
-
- if( ( *pRScan & cBit ) == cBlack )
- {
- pWScan[ 0 ] = COLOR_CHANNEL_MERGE( pWScan[ 0 ], nB, cTrans );
- pWScan[ 1 ] = COLOR_CHANNEL_MERGE( pWScan[ 1 ], nG, cTrans );
- pWScan[ 2 ] = COLOR_CHANNEL_MERGE( pWScan[ 2 ], nR, cTrans );
- }
- }
- }
- }
- else
- {
- for( nY = 0; nY < nHeight; nY++ )
- {
- for( nX = 0; nX < nWidth; nX++ )
- {
- if( pR->GetPixel( nY, nX ) == aBlack )
- {
- aPixCol = pW->GetColor( nY, nX );
- pW->SetPixel( nY, nX, aPixCol.Merge( aFillCol, cTrans ) );
- }
- }
- }
- }
- }
- }
-
- aPolyMask.ReleaseAccess( pR );
- aPaint.ReleaseAccess( pW );
-
- DrawBitmap( aDstRect.TopLeft(), aPaint );
-
- EnableMapMode( bOldMap );
-
- if( mbLineColor )
- {
- Push( PUSH_FILLCOLOR );
- SetFillColor();
- DrawPolyPolygon( rPolyPoly );
- Pop();
- }
- }
- }
- else
- DrawPolyPolygon( rPolyPoly );
- }
- }
-
- mpMetaFile = pOldMetaFile;
-
- // #110958# Restore disabled alpha VDev
- mpAlphaVDev = pOldAlphaVDev;
-}
-
-void OutputDevice::DrawTransparent( const PolyPolygon& rPolyPoly,
- sal_uInt16 nTransparencePercent )
-{
- // short circuit for drawing an opaque polygon
- if( (nTransparencePercent < 1) || ((mnDrawMode & DRAWMODE_NOTRANSPARENCY) != 0) )
- {
- DrawPolyPolygon( rPolyPoly );
- return;
- }
-
- // short circuit for drawing an invisible polygon
- if( !mbFillColor || (nTransparencePercent >= 100) )
- {
- DrawInvisiblePolygon( rPolyPoly );
- }
-
- // handle metafile recording
- if( mpMetaFile )
- mpMetaFile->AddAction( new MetaTransparentAction( rPolyPoly, nTransparencePercent ) );
-
- bool bDrawn = !IsDeviceOutputNecessary() || ImplIsRecordLayout();
- if( bDrawn )
- return;
-
- // get the device graphics as drawing target
- if( !mpGraphics )
- if( !ImplGetGraphics() )
- return;
-
- // try hard to draw it directly, because the emulation layers are slower
- bDrawn = DrawTransparentNatively( rPolyPoly, nTransparencePercent );
- if( bDrawn )
- return;
-
- EmulateDrawTransparent( rPolyPoly, nTransparencePercent );
-
- // #110958# Apply alpha value also to VDev alpha channel
- if( mpAlphaVDev )
- {
- const Color aFillCol( mpAlphaVDev->GetFillColor() );
- mpAlphaVDev->SetFillColor( Color(sal::static_int_cast<sal_uInt8>(255*nTransparencePercent/100),
- sal::static_int_cast<sal_uInt8>(255*nTransparencePercent/100),
- sal::static_int_cast<sal_uInt8>(255*nTransparencePercent/100)) );
-
- mpAlphaVDev->DrawTransparent( rPolyPoly, nTransparencePercent );
-
- mpAlphaVDev->SetFillColor( aFillCol );
- }
-}
-
-void OutputDevice::DrawTransparent( const GDIMetaFile& rMtf, const Point& rPos,
- const Size& rSize, const Gradient& rTransparenceGradient )
-{
-
- const Color aBlack( COL_BLACK );
-
- if( mpMetaFile )
- {
- // missing here is to map the data using the DeviceTransformation
- mpMetaFile->AddAction( new MetaFloatTransparentAction( rMtf, rPos, rSize, rTransparenceGradient ) );
- }
-
- if ( !IsDeviceOutputNecessary() )
- return;
-
- if( ( rTransparenceGradient.GetStartColor() == aBlack && rTransparenceGradient.GetEndColor() == aBlack ) ||
- ( mnDrawMode & ( DRAWMODE_NOTRANSPARENCY ) ) )
- {
- ( (GDIMetaFile&) rMtf ).WindStart();
- ( (GDIMetaFile&) rMtf ).Play( this, rPos, rSize );
- ( (GDIMetaFile&) rMtf ).WindStart();
- }
- else
- {
- GDIMetaFile* pOldMetaFile = mpMetaFile;
- Rectangle aOutRect( LogicToPixel( rPos ), LogicToPixel( rSize ) );
- Point aPoint;
- Rectangle aDstRect( aPoint, GetOutputSizePixel() );
-
- mpMetaFile = NULL;
- aDstRect.Intersection( aOutRect );
-
- ClipToPaintRegion( aDstRect );
-
- if( !aDstRect.IsEmpty() )
- {
- boost::scoped_ptr<VirtualDevice> pVDev(new VirtualDevice);
-
- ((OutputDevice*)pVDev.get())->mnDPIX = mnDPIX;
- ((OutputDevice*)pVDev.get())->mnDPIY = mnDPIY;
-
- if( pVDev->SetOutputSizePixel( aDstRect.GetSize() ) )
- {
- if(GetAntialiasing())
- {
- // #i102109#
- // For MetaFile replay (see task) it may now be necessary to take
- // into account that the content is AntiAlialised and needs to be masked
- // like that. Instead of masking, i will use a copy-modify-paste cycle
- // here (as i already use in the VclPrimiziveRenderer with successs)
- pVDev->SetAntialiasing(GetAntialiasing());
-
- // create MapMode for buffer (offset needed) and set
- MapMode aMap(GetMapMode());
- const Point aOutPos(PixelToLogic(aDstRect.TopLeft()));
- aMap.SetOrigin(Point(-aOutPos.X(), -aOutPos.Y()));
- pVDev->SetMapMode(aMap);
-
- // copy MapMode state and disable for target
- const bool bOrigMapModeEnabled(IsMapModeEnabled());
- EnableMapMode(false);
-
- // copy MapMode state and disable for buffer
- const bool bBufferMapModeEnabled(pVDev->IsMapModeEnabled());
- pVDev->EnableMapMode(false);
-
- // copy content from original to buffer
- pVDev->DrawOutDev(
- aPoint, pVDev->GetOutputSizePixel(), // dest
- aDstRect.TopLeft(), pVDev->GetOutputSizePixel(), // source
- *this);
-
- // draw MetaFile to buffer
- pVDev->EnableMapMode(bBufferMapModeEnabled);
- ((GDIMetaFile&)rMtf).WindStart();
- ((GDIMetaFile&)rMtf).Play(pVDev.get(), rPos, rSize);
- ((GDIMetaFile&)rMtf).WindStart();
-
- // get content bitmap from buffer
- pVDev->EnableMapMode(false);
- const Bitmap aPaint(pVDev->GetBitmap(aPoint, pVDev->GetOutputSizePixel()));
-
- // create alpha mask from gradient and get as Bitmap
- pVDev->EnableMapMode(bBufferMapModeEnabled);
- pVDev->SetDrawMode(DRAWMODE_GRAYGRADIENT);
- pVDev->DrawGradient(Rectangle(rPos, rSize), rTransparenceGradient);
- pVDev->SetDrawMode(DRAWMODE_DEFAULT);
- pVDev->EnableMapMode(false);
- const AlphaMask aAlpha(pVDev->GetBitmap(aPoint, pVDev->GetOutputSizePixel()));
-
- pVDev.reset();
-
- // draw masked content to target and restore MapMode
- DrawBitmapEx(aDstRect.TopLeft(), BitmapEx(aPaint, aAlpha));
- EnableMapMode(bOrigMapModeEnabled);
- }
- else
- {
- Bitmap aPaint, aMask;
- AlphaMask aAlpha;
- MapMode aMap( GetMapMode() );
- Point aOutPos( PixelToLogic( aDstRect.TopLeft() ) );
- const bool bOldMap = mbMap;
-
- aMap.SetOrigin( Point( -aOutPos.X(), -aOutPos.Y() ) );
- pVDev->SetMapMode( aMap );
- const bool bVDevOldMap = pVDev->IsMapModeEnabled();
-
- // create paint bitmap
- ( (GDIMetaFile&) rMtf ).WindStart();
- ( (GDIMetaFile&) rMtf ).Play( pVDev.get(), rPos, rSize );
- ( (GDIMetaFile&) rMtf ).WindStart();
- pVDev->EnableMapMode( false );
- aPaint = pVDev->GetBitmap( Point(), pVDev->GetOutputSizePixel() );
- pVDev->EnableMapMode( bVDevOldMap ); // #i35331#: MUST NOT use EnableMapMode( sal_True ) here!
-
- // create mask bitmap
- pVDev->SetLineColor( COL_BLACK );
- pVDev->SetFillColor( COL_BLACK );
- pVDev->DrawRect( Rectangle( pVDev->PixelToLogic( Point() ), pVDev->GetOutputSize() ) );
- pVDev->SetDrawMode( DRAWMODE_WHITELINE | DRAWMODE_WHITEFILL | DRAWMODE_WHITETEXT |
- DRAWMODE_WHITEBITMAP | DRAWMODE_WHITEGRADIENT );
- ( (GDIMetaFile&) rMtf ).WindStart();
- ( (GDIMetaFile&) rMtf ).Play( pVDev.get(), rPos, rSize );
- ( (GDIMetaFile&) rMtf ).WindStart();
- pVDev->EnableMapMode( false );
- aMask = pVDev->GetBitmap( Point(), pVDev->GetOutputSizePixel() );
- pVDev->EnableMapMode( bVDevOldMap ); // #i35331#: MUST NOT use EnableMapMode( sal_True ) here!
-
- // create alpha mask from gradient
- pVDev->SetDrawMode( DRAWMODE_GRAYGRADIENT );
- pVDev->DrawGradient( Rectangle( rPos, rSize ), rTransparenceGradient );
- pVDev->SetDrawMode( DRAWMODE_DEFAULT );
- pVDev->EnableMapMode( false );
- pVDev->DrawMask( Point(), pVDev->GetOutputSizePixel(), aMask, Color( COL_WHITE ) );
-
- aAlpha = pVDev->GetBitmap( Point(), pVDev->GetOutputSizePixel() );
-
- pVDev.reset();
-
- EnableMapMode( false );
- DrawBitmapEx( aDstRect.TopLeft(), BitmapEx( aPaint, aAlpha ) );
- EnableMapMode( bOldMap );
- }
- }
- }
-
- mpMetaFile = pOldMetaFile;
- }
-}
-
-void OutputDevice::ImplDrawColorWallpaper( long nX, long nY,
- long nWidth, long nHeight,
- const Wallpaper& rWallpaper )
-{
- // draw wallpaper without border
- Color aOldLineColor = GetLineColor();
- Color aOldFillColor = GetFillColor();
- SetLineColor();
- SetFillColor( rWallpaper.GetColor() );
- bool bMap = mbMap;
- EnableMapMode( false );
- DrawRect( Rectangle( Point( nX, nY ), Size( nWidth, nHeight ) ) );
- SetLineColor( aOldLineColor );
- SetFillColor( aOldFillColor );
- EnableMapMode( bMap );
-}
-
-void OutputDevice::ImplDrawBitmapWallpaper( long nX, long nY,
- long nWidth, long nHeight,
- const Wallpaper& rWallpaper )
-{
- BitmapEx aBmpEx;
- const BitmapEx* pCached = rWallpaper.ImplGetImpWallpaper()->ImplGetCachedBitmap();
- Point aPos;
- Size aSize;
- GDIMetaFile* pOldMetaFile = mpMetaFile;
- const WallpaperStyle eStyle = rWallpaper.GetStyle();
- const bool bOldMap = mbMap;
- bool bDrawn = false;
- bool bDrawGradientBackground = false;
- bool bDrawColorBackground = false;
-
- if( pCached )
- aBmpEx = *pCached;
- else
- aBmpEx = rWallpaper.GetBitmap();
-
- const long nBmpWidth = aBmpEx.GetSizePixel().Width();
- const long nBmpHeight = aBmpEx.GetSizePixel().Height();
- const bool bTransparent = aBmpEx.IsTransparent();
-
- // draw background
- if( bTransparent )
- {
- if( rWallpaper.IsGradient() )
- bDrawGradientBackground = true;
- else
- {
- if( !pCached && !rWallpaper.GetColor().GetTransparency() )
- {
- VirtualDevice aVDev( *this );
- aVDev.SetBackground( rWallpaper.GetColor() );
- aVDev.SetOutputSizePixel( Size( nBmpWidth, nBmpHeight ) );
- aVDev.DrawBitmapEx( Point(), aBmpEx );
- aBmpEx = aVDev.GetBitmap( Point(), aVDev.GetOutputSizePixel() );
- }
-
- bDrawColorBackground = true;
- }
- }
- else if( eStyle != WALLPAPER_TILE && eStyle != WALLPAPER_SCALE )
- {
- if( rWallpaper.IsGradient() )
- bDrawGradientBackground = true;
- else
- bDrawColorBackground = true;
- }
-
- // background of bitmap?
- if( bDrawGradientBackground )
- ImplDrawGradientWallpaper( nX, nY, nWidth, nHeight, rWallpaper );
- else if( bDrawColorBackground && bTransparent )
- {
- ImplDrawColorWallpaper( nX, nY, nWidth, nHeight, rWallpaper );
- bDrawColorBackground = false;
- }
-
- // calc pos and size
- if( rWallpaper.IsRect() )
- {
- const Rectangle aBound( LogicToPixel( rWallpaper.GetRect() ) );
- aPos = aBound.TopLeft();
- aSize = aBound.GetSize();
- }
- else
- {
- aPos = Point( 0, 0 );
- aSize = Size( mnOutWidth, mnOutHeight );
- }
-
- mpMetaFile = NULL;
- EnableMapMode( false );
- Push( PUSH_CLIPREGION );
- IntersectClipRegion( Rectangle( Point( nX, nY ), Size( nWidth, nHeight ) ) );
-
- switch( eStyle )
- {
- case( WALLPAPER_SCALE ):
- {
- if( !pCached || ( pCached->GetSizePixel() != aSize ) )
- {
- if( pCached )
- rWallpaper.ImplGetImpWallpaper()->ImplReleaseCachedBitmap();
-
- aBmpEx = rWallpaper.GetBitmap();
- aBmpEx.Scale( aSize );
- aBmpEx = BitmapEx( aBmpEx.GetBitmap().CreateDisplayBitmap( this ), aBmpEx.GetMask() );
- }
- }
- break;
-
- case( WALLPAPER_TOPLEFT ):
- break;
-
- case( WALLPAPER_TOP ):
- aPos.X() += ( aSize.Width() - nBmpWidth ) >> 1;
- break;
-
- case( WALLPAPER_TOPRIGHT ):
- aPos.X() += ( aSize.Width() - nBmpWidth );
- break;
-
- case( WALLPAPER_LEFT ):
- aPos.Y() += ( aSize.Height() - nBmpHeight ) >> 1;
- break;
-
- case( WALLPAPER_CENTER ):
- {
- aPos.X() += ( aSize.Width() - nBmpWidth ) >> 1;
- aPos.Y() += ( aSize.Height() - nBmpHeight ) >> 1;
- }
- break;
-
- case( WALLPAPER_RIGHT ):
- {
- aPos.X() += ( aSize.Width() - nBmpWidth );
- aPos.Y() += ( aSize.Height() - nBmpHeight ) >> 1;
- }
- break;
-
- case( WALLPAPER_BOTTOMLEFT ):
- aPos.Y() += ( aSize.Height() - nBmpHeight );
- break;
-
- case( WALLPAPER_BOTTOM ):
- {
- aPos.X() += ( aSize.Width() - nBmpWidth ) >> 1;
- aPos.Y() += ( aSize.Height() - nBmpHeight );
- }
- break;
-
- case( WALLPAPER_BOTTOMRIGHT ):
- {
- aPos.X() += ( aSize.Width() - nBmpWidth );
- aPos.Y() += ( aSize.Height() - nBmpHeight );
- }
- break;
-
- default:
- {
- const long nRight = nX + nWidth - 1L;
- const long nBottom = nY + nHeight - 1L;
- long nFirstX;
- long nFirstY;
-
- if( eStyle == WALLPAPER_TILE )
- {
- nFirstX = aPos.X();
- nFirstY = aPos.Y();
- }
- else
- {
- nFirstX = aPos.X() + ( ( aSize.Width() - nBmpWidth ) >> 1 );
- nFirstY = aPos.Y() + ( ( aSize.Height() - nBmpHeight ) >> 1 );
- }
-
- const long nOffX = ( nFirstX - nX ) % nBmpWidth;
- const long nOffY = ( nFirstY - nY ) % nBmpHeight;
- long nStartX = nX + nOffX;
- long nStartY = nY + nOffY;
-
- if( nOffX > 0L )
- nStartX -= nBmpWidth;
-
- if( nOffY > 0L )
- nStartY -= nBmpHeight;
-
- for( long nBmpY = nStartY; nBmpY <= nBottom; nBmpY += nBmpHeight )
- for( long nBmpX = nStartX; nBmpX <= nRight; nBmpX += nBmpWidth )
- DrawBitmapEx( Point( nBmpX, nBmpY ), aBmpEx );
-
- bDrawn = true;
- }
- break;
- }
-
- if( !bDrawn )
- {
- // optimized for non-transparent bitmaps
- if( bDrawColorBackground )
- {
- const Size aBmpSize( aBmpEx.GetSizePixel() );
- const Point aTmpPoint;
- const Rectangle aOutRect( aTmpPoint, GetOutputSizePixel() );
- const Rectangle aColRect( Point( nX, nY ), Size( nWidth, nHeight ) );
- Rectangle aWorkRect;
-
- aWorkRect = Rectangle( 0, 0, aOutRect.Right(), aPos.Y() - 1L );
- aWorkRect.Justify();
- aWorkRect.Intersection( aColRect );
- if( !aWorkRect.IsEmpty() )
- {
- ImplDrawColorWallpaper( aWorkRect.Left(), aWorkRect.Top(),
- aWorkRect.GetWidth(), aWorkRect.GetHeight(),
- rWallpaper );
- }
-
- aWorkRect = Rectangle( 0, aPos.Y(), aPos.X() - 1L, aPos.Y() + aBmpSize.Height() - 1L );
- aWorkRect.Justify();
- aWorkRect.Intersection( aColRect );
- if( !aWorkRect.IsEmpty() )
- {
- ImplDrawColorWallpaper( aWorkRect.Left(), aWorkRect.Top(),
- aWorkRect.GetWidth(), aWorkRect.GetHeight(),
- rWallpaper );
- }
-
- aWorkRect = Rectangle( aPos.X() + aBmpSize.Width(), aPos.Y(), aOutRect.Right(), aPos.Y() + aBmpSize.Height() - 1L );
- aWorkRect.Justify();
- aWorkRect.Intersection( aColRect );
- if( !aWorkRect.IsEmpty() )
- {
- ImplDrawColorWallpaper( aWorkRect.Left(), aWorkRect.Top(),
- aWorkRect.GetWidth(), aWorkRect.GetHeight(),
- rWallpaper );
- }
-
- aWorkRect = Rectangle( 0, aPos.Y() + aBmpSize.Height(), aOutRect.Right(), aOutRect.Bottom() );
- aWorkRect.Justify();
- aWorkRect.Intersection( aColRect );
- if( !aWorkRect.IsEmpty() )
- {
- ImplDrawColorWallpaper( aWorkRect.Left(), aWorkRect.Top(),
- aWorkRect.GetWidth(), aWorkRect.GetHeight(),
- rWallpaper );
- }
- }
-
- DrawBitmapEx( aPos, aBmpEx );
- }
-
- rWallpaper.ImplGetImpWallpaper()->ImplSetCachedBitmap( aBmpEx );
-
- Pop();
- EnableMapMode( bOldMap );
- mpMetaFile = pOldMetaFile;
-}
-
-void OutputDevice::ImplDrawGradientWallpaper( long nX, long nY,
- long nWidth, long nHeight,
- const Wallpaper& rWallpaper )
-{
- Rectangle aBound;
- GDIMetaFile* pOldMetaFile = mpMetaFile;
- const bool bOldMap = mbMap;
- bool bNeedGradient = true;
-
- aBound = Rectangle( Point( nX, nY ), Size( nWidth, nHeight ) );
-
- mpMetaFile = NULL;
- EnableMapMode( false );
- Push( PUSH_CLIPREGION );
- IntersectClipRegion( Rectangle( Point( nX, nY ), Size( nWidth, nHeight ) ) );
-
- if( OUTDEV_WINDOW == meOutDevType && rWallpaper.GetStyle() == WALLPAPER_APPLICATIONGRADIENT )
- {
- Window *pWin = dynamic_cast< Window* >( this );
- if( pWin )
- {
- // limit gradient to useful size, so that it still can be noticed
- // in maximized windows
- long gradientWidth = pWin->GetDesktopRectPixel().GetSize().Width();
- if( gradientWidth > 1024 )
- gradientWidth = 1024;
- if( mnOutOffX+nWidth > gradientWidth )
- ImplDrawColorWallpaper( nX, nY, nWidth, nHeight, rWallpaper.GetGradient().GetEndColor() );
- if( mnOutOffX > gradientWidth )
- bNeedGradient = false;
- else
- aBound = Rectangle( Point( -mnOutOffX, nY ), Size( gradientWidth, nHeight ) );
- }
- }
-
- if( bNeedGradient )
- DrawGradient( aBound, rWallpaper.GetGradient() );
-
- Pop();
- EnableMapMode( bOldMap );
- mpMetaFile = pOldMetaFile;
-}
-
-void OutputDevice::ImplDrawWallpaper( long nX, long nY,
- long nWidth, long nHeight,
- const Wallpaper& rWallpaper )
-{
- if( rWallpaper.IsBitmap() )
- ImplDrawBitmapWallpaper( nX, nY, nWidth, nHeight, rWallpaper );
- else if( rWallpaper.IsGradient() )
- ImplDrawGradientWallpaper( nX, nY, nWidth, nHeight, rWallpaper );
- else
- ImplDrawColorWallpaper( nX, nY, nWidth, nHeight, rWallpaper );
-}
-
-void OutputDevice::DrawWallpaper( const Rectangle& rRect,
- const Wallpaper& rWallpaper )
-{
- if ( mpMetaFile )
- mpMetaFile->AddAction( new MetaWallpaperAction( rRect, rWallpaper ) );
-
- if ( !IsDeviceOutputNecessary() || ImplIsRecordLayout() )
- return;
-
- if ( rWallpaper.GetStyle() != WALLPAPER_NULL )
- {
- Rectangle aRect = LogicToPixel( rRect );
- aRect.Justify();
-
- if ( !aRect.IsEmpty() )
- {
- ImplDrawWallpaper( aRect.Left(), aRect.Top(), aRect.GetWidth(), aRect.GetHeight(),
- rWallpaper );
- }
- }
-
- if( mpAlphaVDev )
- mpAlphaVDev->DrawWallpaper( rRect, rWallpaper );
-}
-
-void OutputDevice::Erase()
-{
- if ( !IsDeviceOutputNecessary() || ImplIsRecordLayout() )
- return;
-
- bool bNativeOK = false;
-
- if( meOutDevType == OUTDEV_WINDOW )
- {
- Window* pWindow = static_cast<Window*>(this);
- ControlPart aCtrlPart = pWindow->ImplGetWindowImpl()->mnNativeBackground;
- if( aCtrlPart != 0 && ! pWindow->IsControlBackground() )
- {
- ImplControlValue aControlValue;
- Point aGcc3WorkaroundTemporary;
- Rectangle aCtrlRegion( aGcc3WorkaroundTemporary, GetOutputSizePixel() );
- ControlState nState = 0;
-
- if( pWindow->IsEnabled() ) nState |= CTRL_STATE_ENABLED;
- bNativeOK = pWindow->DrawNativeControl( CTRL_WINDOW_BACKGROUND, aCtrlPart, aCtrlRegion,
- nState, aControlValue, OUString() );
- }
- }
-
- if ( mbBackground && ! bNativeOK )
- {
- RasterOp eRasterOp = GetRasterOp();
- if ( eRasterOp != ROP_OVERPAINT )
- SetRasterOp( ROP_OVERPAINT );
- ImplDrawWallpaper( 0, 0, mnOutWidth, mnOutHeight, maBackground );
- if ( eRasterOp != ROP_OVERPAINT )
- SetRasterOp( eRasterOp );
- }
-
- if( mpAlphaVDev )
- mpAlphaVDev->Erase();
-}
-
-bool OutputDevice::DrawEPS( const Point& rPoint, const Size& rSize,
- const GfxLink& rGfxLink, GDIMetaFile* pSubst )
-{
- bool bDrawn(true);
-
- if ( mpMetaFile )
- {
- GDIMetaFile aSubst;
-
- if( pSubst )
- aSubst = *pSubst;
-
- mpMetaFile->AddAction( new MetaEPSAction( rPoint, rSize, rGfxLink, aSubst ) );
- }
-
- if ( !IsDeviceOutputNecessary() || ImplIsRecordLayout() )
- return bDrawn;
-
- if( mbOutputClipped )
- return bDrawn;
-
- Rectangle aRect( ImplLogicToDevicePixel( Rectangle( rPoint, rSize ) ) );
-
- if( !aRect.IsEmpty() )
- {
- // draw the real EPS graphics
- if( rGfxLink.GetData() && rGfxLink.GetDataSize() )
- {
- if( !mpGraphics && !ImplGetGraphics() )
- return bDrawn;
-
- if( mbInitClipRegion )
- ImplInitClipRegion();
-
- aRect.Justify();
- bDrawn = mpGraphics->DrawEPS( aRect.Left(), aRect.Top(), aRect.GetWidth(), aRect.GetHeight(),
- (sal_uInt8*) rGfxLink.GetData(), rGfxLink.GetDataSize(), this );
- }
-
- // else draw the substitution graphics
- if( !bDrawn && pSubst )
- {
- GDIMetaFile* pOldMetaFile = mpMetaFile;
-
- mpMetaFile = NULL;
- Graphic( *pSubst ).Draw( this, rPoint, rSize );
- mpMetaFile = pOldMetaFile;
- }
- }
-
- if( mpAlphaVDev )
- mpAlphaVDev->DrawEPS( rPoint, rSize, rGfxLink, pSubst );
-
- return bDrawn;
-}
-
-void OutputDevice::DrawCheckered(const Point& rPos, const Size& rSize, sal_uInt32 nLen, Color aStart, Color aEnd)
-{
- const sal_uInt32 nMaxX(rPos.X() + rSize.Width());
- const sal_uInt32 nMaxY(rPos.Y() + rSize.Height());
-
- Push(PUSH_LINECOLOR|PUSH_FILLCOLOR);
- SetLineColor();
-
- for(sal_uInt32 x(0), nX(rPos.X()); nX < nMaxX; x++, nX += nLen)
- {
- const sal_uInt32 nRight(std::min(nMaxX, nX + nLen));
-
- for(sal_uInt32 y(0), nY(rPos.Y()); nY < nMaxY; y++, nY += nLen)
- {
- const sal_uInt32 nBottom(std::min(nMaxY, nY + nLen));
-
- SetFillColor((x & 0x0001) ^ (y & 0x0001) ? aStart : aEnd);
- DrawRect(Rectangle(nX, nY, nRight, nBottom));
- }
- }
-
- Pop();
-}
-
-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/source/outdev/polygon.cxx b/vcl/source/outdev/polygon.cxx
index 09561a6..312625d 100644
--- a/vcl/source/outdev/polygon.cxx
+++ b/vcl/source/outdev/polygon.cxx
@@ -476,3 +476,97 @@ void OutputDevice::ImplDrawPolyPolygon( const PolyPolygon& rPolyPoly, const Poly
if( pClipPolyPoly )
delete pPolyPoly;
}
+
+void OutputDevice::DrawGrid( const Rectangle& rRect, const Size& rDist, sal_uLong nFlags )
+{
+
+ Rectangle aDstRect( PixelToLogic( Point() ), GetOutputSize() );
+ aDstRect.Intersection( rRect );
+
+ if( aDstRect.IsEmpty() || ImplIsRecordLayout() )
+ return;
+
+ if( !mpGraphics && !ImplGetGraphics() )
+ return;
+
+ if( mbInitClipRegion )
+ ImplInitClipRegion();
+
+ if( mbOutputClipped )
+ return;
+
+ const long nDistX = std::max( rDist.Width(), 1L );
+ const long nDistY = std::max( rDist.Height(), 1L );
+ long nX = ( rRect.Left() >= aDstRect.Left() ) ? rRect.Left() : ( rRect.Left() + ( ( aDstRect.Left() - rRect.Left() ) / nDistX ) * nDistX );
+ long nY = ( rRect.Top() >= aDstRect.Top() ) ? rRect.Top() : ( rRect.Top() + ( ( aDstRect.Top() - rRect.Top() ) / nDistY ) * nDistY );
+ const long nRight = aDstRect.Right();
+ const long nBottom = aDstRect.Bottom();
+ const long nStartX = ImplLogicXToDevicePixel( nX );
+ const long nEndX = ImplLogicXToDevicePixel( nRight );
+ const long nStartY = ImplLogicYToDevicePixel( nY );
+ const long nEndY = ImplLogicYToDevicePixel( nBottom );
+ long nHorzCount = 0L;
+ long nVertCount = 0L;
+
+ ::com::sun::star::uno::Sequence< sal_Int32 > aVertBuf;
+ ::com::sun::star::uno::Sequence< sal_Int32 > aHorzBuf;
+
+ if( ( nFlags & GRID_DOTS ) || ( nFlags & GRID_HORZLINES ) )
+ {
+ aVertBuf.realloc( aDstRect.GetHeight() / nDistY + 2L );
+ aVertBuf[ nVertCount++ ] = nStartY;
+ while( ( nY += nDistY ) <= nBottom )
+ aVertBuf[ nVertCount++ ] = ImplLogicYToDevicePixel( nY );
+ }
+
+ if( ( nFlags & GRID_DOTS ) || ( nFlags & GRID_VERTLINES ) )
+ {
+ aHorzBuf.realloc( aDstRect.GetWidth() / nDistX + 2L );
+ aHorzBuf[ nHorzCount++ ] = nStartX;
+ while( ( nX += nDistX ) <= nRight )
+ aHorzBuf[ nHorzCount++ ] = ImplLogicXToDevicePixel( nX );
+ }
+
+ if( mbInitLineColor )
+ ImplInitLineColor();
+
+ if( mbInitFillColor )
+ ImplInitFillColor();
+
+ const bool bOldMap = mbMap;
+ EnableMapMode( false );
+
+ if( nFlags & GRID_DOTS )
+ {
+ for( long i = 0L; i < nVertCount; i++ )
+ for( long j = 0L, Y = aVertBuf[ i ]; j < nHorzCount; j++ )
+ mpGraphics->DrawPixel( aHorzBuf[ j ], Y, this );
+ }
+ else
+ {
+ if( nFlags & GRID_HORZLINES )
+ {
+ for( long i = 0L; i < nVertCount; i++ )
+ {
+ nY = aVertBuf[ i ];
+ mpGraphics->DrawLine( nStartX, nY, nEndX, nY, this );
+ }
+ }
+
+ if( nFlags & GRID_VERTLINES )
+ {
+ for( long i = 0L; i < nHorzCount; i++ )
+ {
+ nX = aHorzBuf[ i ];
+ mpGraphics->DrawLine( nX, nStartY, nX, nEndY, this );
+ }
+ }
+ }
+
+ EnableMapMode( bOldMap );
+
+ if( mpAlphaVDev )
+ mpAlphaVDev->DrawGrid( rRect, rDist, nFlags );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/source/outdev/transparent.cxx b/vcl/source/outdev/transparent.cxx
index 9bc8e39..c5b630a 100644
--- a/vcl/source/outdev/transparent.cxx
+++ b/vcl/source/outdev/transparent.cxx
@@ -40,6 +40,48 @@
#include <basegfx/matrix/b2dhommatrixtools.hxx>
#include <boost/scoped_array.hpp>
+
+namespace
+{
+ /**
+ * Perform a safe approximation of a polygon from double-precision
+ * coordinates to integer coordinates, to ensure that it has at least 2
+ * pixels in both X and Y directions.
+ */
+ Polygon toPolygon( const basegfx::B2DPolygon& rPoly )
+ {
+ basegfx::B2DRange aRange = rPoly.getB2DRange();
+ double fW = aRange.getWidth(), fH = aRange.getHeight();
+ if (0.0 < fW && 0.0 < fH && (fW <= 1.0 || fH <= 1.0))
+ {
+ // This polygon not empty but is too small to display. Approximate it
+ // with a rectangle large enough to be displayed.
+ double nX = aRange.getMinX(), nY = aRange.getMinY();
+ double nW = std::max<double>(1.0, rtl::math::round(fW));
+ double nH = std::max<double>(1.0, rtl::math::round(fH));
+
+ Polygon aTarget;
+ aTarget.Insert(0, Point(nX, nY));
+ aTarget.Insert(1, Point(nX+nW, nY));
+ aTarget.Insert(2, Point(nX+nW, nY+nH));
+ aTarget.Insert(3, Point(nX, nY+nH));
+ aTarget.Insert(4, Point(nX, nY));
+ return aTarget;
+ }
+ return Polygon(rPoly);
+ }
+
+ PolyPolygon toPolyPolygon( const basegfx::B2DPolyPolygon& rPolyPoly )
+ {
+ PolyPolygon aTarget;
+ for (sal_uInt32 i = 0; i < rPolyPoly.count(); ++i)
+ aTarget.Insert(toPolygon(rPolyPoly.getB2DPolygon(i)));
+
+ return aTarget;
+ }
+
+}
+
void OutputDevice::ImplPrintTransparent( const Bitmap& rBmp, const Bitmap& rMask,
const Point& rDestPt, const Size& rDestSize,
const Point& rSrcPtPixel, const Size& rSrcSizePixel )
@@ -133,4 +175,565 @@ void OutputDevice::ImplPrintTransparent( const Bitmap& rBmp, const Bitmap& rMask
}
}
+// Caution: This method is nearly the same as
+// void OutputDevice::DrawPolyPolygon( const basegfx::B2DPolyPolygon& rB2DPolyPoly )
+// so when changes are made here do not forget to make changes there, too
+
+void OutputDevice::DrawTransparent( const basegfx::B2DPolyPolygon& rB2DPolyPoly, double fTransparency)
+{
+ // AW: Do NOT paint empty PolyPolygons
+ if(!rB2DPolyPoly.count())
+ return;
+
+ // we need a graphics
+ if( !mpGraphics )
+ if( !ImplGetGraphics() )
+ return;
+
+ if( mbInitClipRegion )
+ ImplInitClipRegion();
+ if( mbOutputClipped )
+ return;
+
+ if( mbInitLineColor )
+ ImplInitLineColor();
+ if( mbInitFillColor )
+ ImplInitFillColor();
+
+ if((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW)
+ && mpGraphics->supportsOperation(OutDevSupport_B2DDraw)
+ && ROP_OVERPAINT == GetRasterOp() )
+ {
+ // b2dpolygon support not implemented yet on non-UNX platforms
+ const ::basegfx::B2DHomMatrix aTransform = ImplGetDeviceTransformation();
+ basegfx::B2DPolyPolygon aB2DPolyPolygon(rB2DPolyPoly);
+
+ // transform the polygon into device space and ensure it is closed
+ aB2DPolyPolygon.transform( aTransform );
+ aB2DPolyPolygon.setClosed( true );
+
+ bool bDrawnOk = true;
+ if( IsFillColor() )
+ bDrawnOk = mpGraphics->DrawPolyPolygon( aB2DPolyPolygon, fTransparency, this );
+ if( bDrawnOk && IsLineColor() )
+ {
+ const basegfx::B2DVector aHairlineWidth(1,1);
+ const int nPolyCount = aB2DPolyPolygon.count();
+ for( int nPolyIdx = 0; nPolyIdx < nPolyCount; ++nPolyIdx )
+ {
+ const ::basegfx::B2DPolygon aOnePoly = aB2DPolyPolygon.getB2DPolygon( nPolyIdx );
+ mpGraphics->DrawPolyLine( aOnePoly, fTransparency, aHairlineWidth, ::basegfx::B2DLINEJOIN_NONE, com::sun::star::drawing::LineCap_BUTT, this );
+ }
+ }
+
+ if( bDrawnOk )
+ {
+ if( mpMetaFile )
+ mpMetaFile->AddAction( new MetaTransparentAction( PolyPolygon( rB2DPolyPoly ), static_cast< sal_uInt16 >(fTransparency * 100.0)));
+ return;
+ }
+ }
+
+ // fallback to old polygon drawing if needed
+ DrawTransparent(toPolyPolygon(rB2DPolyPoly), static_cast<sal_uInt16>(fTransparency * 100.0));
+}
+
+void OutputDevice::DrawInvisiblePolygon( const PolyPolygon& rPolyPoly )
+{
+ // short circuit if the polygon border is invisible too
+ if( !mbLineColor )
+ return;
+
+ // we assume that the border is NOT to be drawn transparently???
+ Push( PUSH_FILLCOLOR );
+ SetFillColor();
+ DrawPolyPolygon( rPolyPoly );
+ Pop();
+}
+
+bool OutputDevice::DrawTransparentNatively ( const PolyPolygon& rPolyPoly,
+ sal_uInt16 nTransparencePercent )
+{
+ bool bDrawn = false;
+
+ // debug helper:
+ static const char* pDisableNative = getenv( "SAL_DISABLE_NATIVE_ALPHA");
+
+ if( !pDisableNative
+ && mpGraphics->supportsOperation( OutDevSupport_B2DDraw )
+#if defined UNX && ! defined MACOSX && ! defined IOS
+ && GetBitCount() > 8
+#endif
+#ifdef WIN32
+ // workaround bad dithering on remote displaying when using GDI+ with toolbar button highlighting
+ && !rPolyPoly.IsRect()
+#endif
+ )
+ {
+ // prepare the graphics device
+ if( mbInitClipRegion )
+ ImplInitClipRegion();
+ if( mbOutputClipped )
+ return false;
+ if( mbInitLineColor )
+ ImplInitLineColor();
+ if( mbInitFillColor )
+ ImplInitFillColor();
+
+ // get the polygon in device coordinates
+ basegfx::B2DPolyPolygon aB2DPolyPolygon( rPolyPoly.getB2DPolyPolygon() );
+ const ::basegfx::B2DHomMatrix aTransform = ImplGetDeviceTransformation();
+ aB2DPolyPolygon.transform( aTransform );
+
+ const double fTransparency = 0.01 * nTransparencePercent;
+ if( mbFillColor )
+ {
+ // #i121591#
+ // CAUTION: Only non printing (pixel-renderer) VCL commands from OutputDevices
+ // should be used when printing. Normally this is avoided by the printer being
+ // non-AAed and thus e.g. on WIN GdiPlus calls are not used. It may be necessary
+ // to figure out a way of moving this code to it's own function that is
+ // overriden by the Print class, which will mean we deliberately override the
+ // functionality and we use the fallback some lines below (which is not very good,
+ // though. For now, WinSalGraphics::drawPolyPolygon will detect printer usage and
+ // correct the wrong mapping (see there for details)
+ bDrawn = mpGraphics->DrawPolyPolygon( aB2DPolyPolygon, fTransparency, this );
+ }
+
+ if( mbLineColor )
+ {
+ // disable the fill color for now
+ mpGraphics->SetFillColor();
+ // draw the border line
+ const basegfx::B2DVector aLineWidths( 1, 1 );
+ const int nPolyCount = aB2DPolyPolygon.count();
+ for( int nPolyIdx = 0; nPolyIdx < nPolyCount; ++nPolyIdx )
+ {
+ const ::basegfx::B2DPolygon& rPolygon = aB2DPolyPolygon.getB2DPolygon( nPolyIdx );
+ bDrawn = mpGraphics->DrawPolyLine( rPolygon, fTransparency, aLineWidths, ::basegfx::B2DLINEJOIN_NONE, com::sun::star::drawing::LineCap_BUTT, this );
+ }
+ // prepare to restore the fill color
+ mbInitFillColor = mbFillColor;
+ }
+ }
+
+ return bDrawn;
+}
+
+void OutputDevice::EmulateDrawTransparent ( const PolyPolygon& rPolyPoly,
+ sal_uInt16 nTransparencePercent )
+{
+ // debug helper:
+ static const char* pDisableNative = getenv( "SAL_DISABLE_NATIVE_ALPHA");
+
+ // #110958# Disable alpha VDev, we perform the necessary
+ VirtualDevice* pOldAlphaVDev = mpAlphaVDev;
+
+ // operation explicitly further below.
+ if( mpAlphaVDev )
+ mpAlphaVDev = NULL;
+
+ GDIMetaFile* pOldMetaFile = mpMetaFile;
+ mpMetaFile = NULL;
+
+ PolyPolygon aPolyPoly( LogicToPixel( rPolyPoly ) );
+ Rectangle aPolyRect( aPolyPoly.GetBoundRect() );
+ Point aPoint;
+ Rectangle aDstRect( aPoint, GetOutputSizePixel() );
+
+ aDstRect.Intersection( aPolyRect );
+
+ ClipToPaintRegion( aDstRect );
+
+ if( !aDstRect.IsEmpty() )
+ {
+ bool bDrawn = false;
+
+ // #i66849# Added fast path for exactly rectangular
+ // polygons
+ // #i83087# Naturally, system alpha blending cannot
+ // work with separate alpha VDev
+ if( !mpAlphaVDev && !pDisableNative && aPolyPoly.IsRect() )
+ {
+ // setup Graphics only here (other cases delegate
+ // to basic OutDev methods)
+ if ( mbInitClipRegion )
+ ImplInitClipRegion();
+ if ( mbInitLineColor )
+ ImplInitLineColor();
+ if ( mbInitFillColor )
+ ImplInitFillColor();
+
+ Rectangle aLogicPolyRect( rPolyPoly.GetBoundRect() );
+ Rectangle aPixelRect( ImplLogicToDevicePixel( aLogicPolyRect ) );
+
+ if( !mbOutputClipped )
+ {
+ bDrawn = mpGraphics->DrawAlphaRect(
+ aPixelRect.Left(), aPixelRect.Top(),
+ // #i98405# use methods with small g, else one pixel too much will be painted.
+ // This is because the source is a polygon which when painted would not paint
+ // the rightmost and lowest pixel line(s), so use one pixel less for the
+ // rectangle, too.
+ aPixelRect.getWidth(), aPixelRect.getHeight(),
+ sal::static_int_cast<sal_uInt8>(nTransparencePercent),
+ this );
+ }
+ else
+ bDrawn = true;
+ }
+
+ if( !bDrawn )
+ {
+ VirtualDevice aVDev( *this, 1 );
+ const Size aDstSz( aDstRect.GetSize() );
+ const sal_uInt8 cTrans = (sal_uInt8) MinMax( FRound( nTransparencePercent * 2.55 ), 0, 255 );
+
+ if( aDstRect.Left() || aDstRect.Top() )
+ aPolyPoly.Move( -aDstRect.Left(), -aDstRect.Top() );
+
+ if( aVDev.SetOutputSizePixel( aDstSz ) )
+ {
+ const bool bOldMap = mbMap;
+
+ EnableMapMode( false );
+
+ aVDev.SetLineColor( COL_BLACK );
+ aVDev.SetFillColor( COL_BLACK );
+ aVDev.DrawPolyPolygon( aPolyPoly );
+
+ Bitmap aPaint( GetBitmap( aDstRect.TopLeft(), aDstSz ) );
+ Bitmap aPolyMask( aVDev.GetBitmap( Point(), aDstSz ) );
+
+ // #107766# check for non-empty bitmaps before accessing them
+ if( !!aPaint && !!aPolyMask )
+ {
+ BitmapWriteAccess* pW = aPaint.AcquireWriteAccess();
+ BitmapReadAccess* pR = aPolyMask.AcquireReadAccess();
+
+ if( pW && pR )
+ {
+ BitmapColor aPixCol;
+ const BitmapColor aFillCol( GetFillColor() );
+ const BitmapColor aWhite( pR->GetBestMatchingColor( Color( COL_WHITE ) ) );
+ const BitmapColor aBlack( pR->GetBestMatchingColor( Color( COL_BLACK ) ) );
+ const long nWidth = pW->Width(), nHeight = pW->Height();
+ const long nR = aFillCol.GetRed(), nG = aFillCol.GetGreen(), nB = aFillCol.GetBlue();
+ long nX, nY;
+
+ if( aPaint.GetBitCount() <= 8 )
+ {
+ const BitmapPalette& rPal = pW->GetPalette();
+ const sal_uInt16 nCount = rPal.GetEntryCount();
+ BitmapColor* pMap = (BitmapColor*) new sal_uInt8[ nCount * sizeof( BitmapColor ) ];
+
+ for( sal_uInt16 i = 0; i < nCount; i++ )
+ {
+ BitmapColor aCol( rPal[ i ] );
+ pMap[ i ] = BitmapColor( (sal_uInt8) rPal.GetBestIndex( aCol.Merge( aFillCol, cTrans ) ) );
+ }
+
+ if( pR->GetScanlineFormat() == BMP_FORMAT_1BIT_MSB_PAL &&
+ pW->GetScanlineFormat() == BMP_FORMAT_8BIT_PAL )
+ {
+ const sal_uInt8 cBlack = aBlack.GetIndex();
+
+ for( nY = 0; nY < nHeight; nY++ )
+ {
+ Scanline pWScan = pW->GetScanline( nY );
+ Scanline pRScan = pR->GetScanline( nY );
+ sal_uInt8 cBit = 128;
+
+ for( nX = 0; nX < nWidth; nX++, cBit >>= 1, pWScan++ )
+ {
+ if( !cBit )
+ cBit = 128, pRScan++;
+
+ if( ( *pRScan & cBit ) == cBlack )
+ *pWScan = (sal_uInt8) pMap[ *pWScan ].GetIndex();
+ }
+ }
+ }
+ else
+ {
+ for( nY = 0; nY < nHeight; nY++ )
+ for( nX = 0; nX < nWidth; nX++ )
+ if( pR->GetPixel( nY, nX ) == aBlack )
+ pW->SetPixel( nY, nX, pMap[ pW->GetPixel( nY, nX ).GetIndex() ] );
+ }
+
+ delete[] (sal_uInt8*) pMap;
+ }
+ else
+ {
+ if( pR->GetScanlineFormat() == BMP_FORMAT_1BIT_MSB_PAL &&
+ pW->GetScanlineFormat() == BMP_FORMAT_24BIT_TC_BGR )
+ {
+ const sal_uInt8 cBlack = aBlack.GetIndex();
+
+ for( nY = 0; nY < nHeight; nY++ )
+ {
+ Scanline pWScan = pW->GetScanline( nY );
+ Scanline pRScan = pR->GetScanline( nY );
+ sal_uInt8 cBit = 128;
+
+ for( nX = 0; nX < nWidth; nX++, cBit >>= 1, pWScan += 3 )
+ {
+ if( !cBit )
+ cBit = 128, pRScan++;
+
+ if( ( *pRScan & cBit ) == cBlack )
+ {
+ pWScan[ 0 ] = COLOR_CHANNEL_MERGE( pWScan[ 0 ], nB, cTrans );
+ pWScan[ 1 ] = COLOR_CHANNEL_MERGE( pWScan[ 1 ], nG, cTrans );
+ pWScan[ 2 ] = COLOR_CHANNEL_MERGE( pWScan[ 2 ], nR, cTrans );
+ }
+ }
+ }
+ }
+ else
+ {
+ for( nY = 0; nY < nHeight; nY++ )
+ {
+ for( nX = 0; nX < nWidth; nX++ )
+ {
+ if( pR->GetPixel( nY, nX ) == aBlack )
+ {
+ aPixCol = pW->GetColor( nY, nX );
+ pW->SetPixel( nY, nX, aPixCol.Merge( aFillCol, cTrans ) );
+ }
+ }
+ }
+ }
+ }
+ }
+
+ aPolyMask.ReleaseAccess( pR );
+ aPaint.ReleaseAccess( pW );
+
+ DrawBitmap( aDstRect.TopLeft(), aPaint );
+
+ EnableMapMode( bOldMap );
+
+ if( mbLineColor )
+ {
+ Push( PUSH_FILLCOLOR );
+ SetFillColor();
+ DrawPolyPolygon( rPolyPoly );
+ Pop();
+ }
+ }
+ }
+ else
+ DrawPolyPolygon( rPolyPoly );
+ }
+ }
+
+ mpMetaFile = pOldMetaFile;
+
+ // #110958# Restore disabled alpha VDev
+ mpAlphaVDev = pOldAlphaVDev;
+}
+
+void OutputDevice::DrawTransparent( const PolyPolygon& rPolyPoly,
+ sal_uInt16 nTransparencePercent )
+{
+ // short circuit for drawing an opaque polygon
+ if( (nTransparencePercent < 1) || ((mnDrawMode & DRAWMODE_NOTRANSPARENCY) != 0) )
+ {
+ DrawPolyPolygon( rPolyPoly );
+ return;
+ }
+
+ // short circuit for drawing an invisible polygon
+ if( !mbFillColor || (nTransparencePercent >= 100) )
+ {
+ DrawInvisiblePolygon( rPolyPoly );
+ }
+
+ // handle metafile recording
+ if( mpMetaFile )
+ mpMetaFile->AddAction( new MetaTransparentAction( rPolyPoly, nTransparencePercent ) );
+
+ bool bDrawn = !IsDeviceOutputNecessary() || ImplIsRecordLayout();
+ if( bDrawn )
+ return;
+
+ // get the device graphics as drawing target
+ if( !mpGraphics )
+ if( !ImplGetGraphics() )
+ return;
+
+ // try hard to draw it directly, because the emulation layers are slower
+ bDrawn = DrawTransparentNatively( rPolyPoly, nTransparencePercent );
+ if( bDrawn )
+ return;
+
+ EmulateDrawTransparent( rPolyPoly, nTransparencePercent );
+
+ // #110958# Apply alpha value also to VDev alpha channel
+ if( mpAlphaVDev )
+ {
+ const Color aFillCol( mpAlphaVDev->GetFillColor() );
+ mpAlphaVDev->SetFillColor( Color(sal::static_int_cast<sal_uInt8>(255*nTransparencePercent/100),
+ sal::static_int_cast<sal_uInt8>(255*nTransparencePercent/100),
+ sal::static_int_cast<sal_uInt8>(255*nTransparencePercent/100)) );
+
+ mpAlphaVDev->DrawTransparent( rPolyPoly, nTransparencePercent );
+
+ mpAlphaVDev->SetFillColor( aFillCol );
+ }
+}
+
+void OutputDevice::DrawTransparent( const GDIMetaFile& rMtf, const Point& rPos,
+ const Size& rSize, const Gradient& rTransparenceGradient )
+{
+
+ const Color aBlack( COL_BLACK );
+
+ if( mpMetaFile )
+ {
+ // missing here is to map the data using the DeviceTransformation
+ mpMetaFile->AddAction( new MetaFloatTransparentAction( rMtf, rPos, rSize, rTransparenceGradient ) );
+ }
+
+ if ( !IsDeviceOutputNecessary() )
+ return;
+
+ if( ( rTransparenceGradient.GetStartColor() == aBlack && rTransparenceGradient.GetEndColor() == aBlack ) ||
+ ( mnDrawMode & ( DRAWMODE_NOTRANSPARENCY ) ) )
+ {
+ ( (GDIMetaFile&) rMtf ).WindStart();
+ ( (GDIMetaFile&) rMtf ).Play( this, rPos, rSize );
+ ( (GDIMetaFile&) rMtf ).WindStart();
+ }
+ else
+ {
+ GDIMetaFile* pOldMetaFile = mpMetaFile;
+ Rectangle aOutRect( LogicToPixel( rPos ), LogicToPixel( rSize ) );
+ Point aPoint;
+ Rectangle aDstRect( aPoint, GetOutputSizePixel() );
+
+ mpMetaFile = NULL;
+ aDstRect.Intersection( aOutRect );
+
+ ClipToPaintRegion( aDstRect );
+
+ if( !aDstRect.IsEmpty() )
+ {
+ boost::scoped_ptr<VirtualDevice> pVDev(new VirtualDevice);
+
+ ((OutputDevice*)pVDev.get())->mnDPIX = mnDPIX;
+ ((OutputDevice*)pVDev.get())->mnDPIY = mnDPIY;
+
+ if( pVDev->SetOutputSizePixel( aDstRect.GetSize() ) )
+ {
+ if(GetAntialiasing())
+ {
+ // #i102109#
+ // For MetaFile replay (see task) it may now be necessary to take
+ // into account that the content is AntiAlialised and needs to be masked
+ // like that. Instead of masking, i will use a copy-modify-paste cycle
+ // here (as i already use in the VclPrimiziveRenderer with successs)
+ pVDev->SetAntialiasing(GetAntialiasing());
+
+ // create MapMode for buffer (offset needed) and set
+ MapMode aMap(GetMapMode());
+ const Point aOutPos(PixelToLogic(aDstRect.TopLeft()));
+ aMap.SetOrigin(Point(-aOutPos.X(), -aOutPos.Y()));
+ pVDev->SetMapMode(aMap);
+
+ // copy MapMode state and disable for target
+ const bool bOrigMapModeEnabled(IsMapModeEnabled());
+ EnableMapMode(false);
+
+ // copy MapMode state and disable for buffer
+ const bool bBufferMapModeEnabled(pVDev->IsMapModeEnabled());
+ pVDev->EnableMapMode(false);
+
+ // copy content from original to buffer
+ pVDev->DrawOutDev(
+ aPoint, pVDev->GetOutputSizePixel(), // dest
+ aDstRect.TopLeft(), pVDev->GetOutputSizePixel(), // source
+ *this);
+
+ // draw MetaFile to buffer
+ pVDev->EnableMapMode(bBufferMapModeEnabled);
+ ((GDIMetaFile&)rMtf).WindStart();
+ ((GDIMetaFile&)rMtf).Play(pVDev.get(), rPos, rSize);
+ ((GDIMetaFile&)rMtf).WindStart();
+
+ // get content bitmap from buffer
+ pVDev->EnableMapMode(false);
+ const Bitmap aPaint(pVDev->GetBitmap(aPoint, pVDev->GetOutputSizePixel()));
+
+ // create alpha mask from gradient and get as Bitmap
+ pVDev->EnableMapMode(bBufferMapModeEnabled);
+ pVDev->SetDrawMode(DRAWMODE_GRAYGRADIENT);
+ pVDev->DrawGradient(Rectangle(rPos, rSize), rTransparenceGradient);
+ pVDev->SetDrawMode(DRAWMODE_DEFAULT);
+ pVDev->EnableMapMode(false);
+ const AlphaMask aAlpha(pVDev->GetBitmap(aPoint, pVDev->GetOutputSizePixel()));
+
+ pVDev.reset();
+
+ // draw masked content to target and restore MapMode
+ DrawBitmapEx(aDstRect.TopLeft(), BitmapEx(aPaint, aAlpha));
+ EnableMapMode(bOrigMapModeEnabled);
+ }
+ else
+ {
+ Bitmap aPaint, aMask;
+ AlphaMask aAlpha;
+ MapMode aMap( GetMapMode() );
+ Point aOutPos( PixelToLogic( aDstRect.TopLeft() ) );
+ const bool bOldMap = mbMap;
+
+ aMap.SetOrigin( Point( -aOutPos.X(), -aOutPos.Y() ) );
+ pVDev->SetMapMode( aMap );
+ const bool bVDevOldMap = pVDev->IsMapModeEnabled();
+
+ // create paint bitmap
+ ( (GDIMetaFile&) rMtf ).WindStart();
+ ( (GDIMetaFile&) rMtf ).Play( pVDev.get(), rPos, rSize );
+ ( (GDIMetaFile&) rMtf ).WindStart();
+ pVDev->EnableMapMode( false );
+ aPaint = pVDev->GetBitmap( Point(), pVDev->GetOutputSizePixel() );
+ pVDev->EnableMapMode( bVDevOldMap ); // #i35331#: MUST NOT use EnableMapMode( sal_True ) here!
+
+ // create mask bitmap
+ pVDev->SetLineColor( COL_BLACK );
+ pVDev->SetFillColor( COL_BLACK );
+ pVDev->DrawRect( Rectangle( pVDev->PixelToLogic( Point() ), pVDev->GetOutputSize() ) );
+ pVDev->SetDrawMode( DRAWMODE_WHITELINE | DRAWMODE_WHITEFILL | DRAWMODE_WHITETEXT |
+ DRAWMODE_WHITEBITMAP | DRAWMODE_WHITEGRADIENT );
+ ( (GDIMetaFile&) rMtf ).WindStart();
+ ( (GDIMetaFile&) rMtf ).Play( pVDev.get(), rPos, rSize );
+ ( (GDIMetaFile&) rMtf ).WindStart();
+ pVDev->EnableMapMode( false );
+ aMask = pVDev->GetBitmap( Point(), pVDev->GetOutputSizePixel() );
+ pVDev->EnableMapMode( bVDevOldMap ); // #i35331#: MUST NOT use EnableMapMode( sal_True ) here!
+
+ // create alpha mask from gradient
+ pVDev->SetDrawMode( DRAWMODE_GRAYGRADIENT );
+ pVDev->DrawGradient( Rectangle( rPos, rSize ), rTransparenceGradient );
+ pVDev->SetDrawMode( DRAWMODE_DEFAULT );
+ pVDev->EnableMapMode( false );
+ pVDev->DrawMask( Point(), pVDev->GetOutputSizePixel(), aMask, Color( COL_WHITE ) );
+
+ aAlpha = pVDev->GetBitmap( Point(), pVDev->GetOutputSizePixel() );
+
+ pVDev.reset();
+
+ EnableMapMode( false );
+ DrawBitmapEx( aDstRect.TopLeft(), BitmapEx( aPaint, aAlpha ) );
+ EnableMapMode( bOldMap );
+ }
+ }
+ }
+
+ mpMetaFile = pOldMetaFile;
+ }
+}
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/source/outdev/wallpaper.cxx b/vcl/source/outdev/wallpaper.cxx
new file mode 100644
index 0000000..c53c1ec
--- /dev/null
+++ b/vcl/source/outdev/wallpaper.cxx
@@ -0,0 +1,384 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
... etc. - the rest is truncated
More information about the Libreoffice-commits
mailing list