summaryrefslogtreecommitdiff
path: root/drawinglayer/source/processor2d/vclhelperbufferdevice.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'drawinglayer/source/processor2d/vclhelperbufferdevice.cxx')
-rw-r--r--drawinglayer/source/processor2d/vclhelperbufferdevice.cxx378
1 files changed, 236 insertions, 142 deletions
diff --git a/drawinglayer/source/processor2d/vclhelperbufferdevice.cxx b/drawinglayer/source/processor2d/vclhelperbufferdevice.cxx
index 647825959108..28d383230eef 100644
--- a/drawinglayer/source/processor2d/vclhelperbufferdevice.cxx
+++ b/drawinglayer/source/processor2d/vclhelperbufferdevice.cxx
@@ -19,7 +19,6 @@
#include <sal/config.h>
#include <sal/log.hxx>
-#include <osl/diagnose.h>
#include <algorithm>
#include <map>
@@ -29,30 +28,39 @@
#include <basegfx/range/b2drange.hxx>
#include <vcl/bitmapex.hxx>
#include <basegfx/matrix/b2dhommatrix.hxx>
-#include <tools/stream.hxx>
+#include <basegfx/matrix/b2dhommatrixtools.hxx>
#include <vcl/timer.hxx>
-#include <cppuhelper/basemutex.hxx>
#include <vcl/lazydelete.hxx>
#include <vcl/dibtools.hxx>
+#include <vcl/skia/SkiaHelper.hxx>
+#include <mutex>
-// buffered VDev usage
+#ifdef DBG_UTIL
+#include <tools/stream.hxx>
+#endif
+// #define SPEED_COMPARE
+#ifdef SPEED_COMPARE
+#include <tools/time.hxx>
+#endif
+
+// buffered VDev usage
namespace
{
-class VDevBuffer : public Timer, protected cppu::BaseMutex
+class VDevBuffer : public Timer
{
private:
struct Entry
{
VclPtr<VirtualDevice> buf;
- bool isTransparent = false;
- Entry(const VclPtr<VirtualDevice>& vdev, bool bTransparent)
+ Entry(const VclPtr<VirtualDevice>& vdev)
: buf(vdev)
- , isTransparent(bTransparent)
{
}
};
+ std::mutex m_aMutex;
+
// available buffers
std::vector<Entry> maFreeBuffers;
@@ -64,12 +72,13 @@ private:
// virtualdevice because that isn't safe to do at least for Gtk2
std::map<VclPtr<VirtualDevice>, VclPtr<OutputDevice>> maDeviceTemplates;
+ static bool isSizeSuitable(const VclPtr<VirtualDevice>& device, const Size& size);
+
public:
VDevBuffer();
virtual ~VDevBuffer() override;
- VclPtr<VirtualDevice> alloc(OutputDevice& rOutDev, const Size& rSizePixel, bool bClear,
- bool bMonoChrome, bool bTransparent);
+ VclPtr<VirtualDevice> alloc(OutputDevice& rOutDev, const Size& rSizePixel);
void free(VirtualDevice& rDevice);
// Timer virtuals
@@ -77,17 +86,14 @@ public:
};
VDevBuffer::VDevBuffer()
- : Timer("VDevBuffer timer")
- , maFreeBuffers()
- , maUsedBuffers()
+ : Timer("drawinglayer::VDevBuffer via Invoke()")
{
SetTimeout(10L * 1000L); // ten seconds
- SetDebugName("drawinglayer::VDevBuffer via Invoke()");
}
VDevBuffer::~VDevBuffer()
{
- ::osl::MutexGuard aGuard(m_aMutex);
+ std::unique_lock aGuard(m_aMutex);
Stop();
while (!maFreeBuffers.empty())
@@ -103,13 +109,40 @@ VDevBuffer::~VDevBuffer()
}
}
-VclPtr<VirtualDevice> VDevBuffer::alloc(OutputDevice& rOutDev, const Size& rSizePixel, bool bClear,
- bool bMonoChrome, bool bTransparent)
+bool VDevBuffer::isSizeSuitable(const VclPtr<VirtualDevice>& device, const Size& rSizePixel)
+{
+ if (device->GetOutputWidthPixel() >= rSizePixel.getWidth()
+ && device->GetOutputHeightPixel() >= rSizePixel.getHeight())
+ {
+ bool requireSmall = false;
+#if defined(UNX)
+ // HACK: See the small size handling in SvpSalVirtualDevice::CreateSurface().
+ // Make sure to not reuse a larger device when a small one should be preferred.
+ if (device->GetRenderBackendName() == "svp")
+ requireSmall = true;
+#endif
+ // The same for Skia, see renderMethodToUseForSize().
+ if (SkiaHelper::isVCLSkiaEnabled())
+ requireSmall = true;
+ if (requireSmall)
+ {
+ if (rSizePixel.getWidth() <= 32 && rSizePixel.getHeight() <= 32
+ && (device->GetOutputWidthPixel() > 32 || device->GetOutputHeightPixel() > 32))
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+ return false;
+}
+
+VclPtr<VirtualDevice> VDevBuffer::alloc(OutputDevice& rOutDev, const Size& rSizePixel)
{
- ::osl::MutexGuard aGuard(m_aMutex);
+ std::unique_lock aGuard(m_aMutex);
VclPtr<VirtualDevice> pRetval;
- sal_Int32 nBits = bMonoChrome ? 1 : rOutDev.GetBitCount();
+ sal_Int32 nBits = rOutDev.GetBitCount();
bool bOkay(false);
if (!maFreeBuffers.empty())
@@ -120,7 +153,7 @@ VclPtr<VirtualDevice> VDevBuffer::alloc(OutputDevice& rOutDev, const Size& rSize
{
assert(a->buf && "Empty pointer in VDevBuffer (!)");
- if (nBits == a->buf->GetBitCount() && bTransparent == a->isTransparent)
+ if (nBits == a->buf->GetBitCount())
{
// candidate is valid due to bit depth
if (aFound != maFreeBuffers.end())
@@ -129,9 +162,7 @@ VclPtr<VirtualDevice> VDevBuffer::alloc(OutputDevice& rOutDev, const Size& rSize
if (bOkay)
{
// found is valid
- const bool bCandidateOkay(
- a->buf->GetOutputWidthPixel() >= rSizePixel.getWidth()
- && a->buf->GetOutputHeightPixel() >= rSizePixel.getHeight());
+ const bool bCandidateOkay = isSizeSuitable(a->buf, rSizePixel);
if (bCandidateOkay)
{
@@ -156,16 +187,14 @@ VclPtr<VirtualDevice> VDevBuffer::alloc(OutputDevice& rOutDev, const Size& rSize
{
// found is invalid, use candidate
aFound = a;
- bOkay = aFound->buf->GetOutputWidthPixel() >= rSizePixel.getWidth()
- && aFound->buf->GetOutputHeightPixel() >= rSizePixel.getHeight();
+ bOkay = isSizeSuitable(aFound->buf, rSizePixel);
}
}
else
{
// none yet, use candidate
aFound = a;
- bOkay = aFound->buf->GetOutputWidthPixel() >= rSizePixel.getWidth()
- && aFound->buf->GetOutputHeightPixel() >= rSizePixel.getHeight();
+ bOkay = isSizeSuitable(aFound->buf, rSizePixel);
}
}
}
@@ -192,15 +221,12 @@ VclPtr<VirtualDevice> VDevBuffer::alloc(OutputDevice& rOutDev, const Size& rSize
{
if (bOkay)
{
- if (bClear)
- {
- pRetval->Erase(
- ::tools::Rectangle(0, 0, rSizePixel.getWidth(), rSizePixel.getHeight()));
- }
+ pRetval->Erase(pRetval->PixelToLogic(
+ tools::Rectangle(0, 0, rSizePixel.getWidth(), rSizePixel.getHeight())));
}
else
{
- pRetval->SetOutputSizePixel(rSizePixel, bClear);
+ pRetval->SetOutputSizePixel(rSizePixel, true);
}
}
}
@@ -208,11 +234,9 @@ VclPtr<VirtualDevice> VDevBuffer::alloc(OutputDevice& rOutDev, const Size& rSize
// no success yet, create new buffer
if (!pRetval)
{
- pRetval = VclPtr<VirtualDevice>::Create(
- rOutDev, bMonoChrome ? DeviceFormat::BITMASK : DeviceFormat::DEFAULT,
- bTransparent ? DeviceFormat::DEFAULT : DeviceFormat::NONE);
+ pRetval = VclPtr<VirtualDevice>::Create(rOutDev, DeviceFormat::WITHOUT_ALPHA);
maDeviceTemplates[pRetval] = &rOutDev;
- pRetval->SetOutputSizePixel(rSizePixel, bClear);
+ pRetval->SetOutputSizePixel(rSizePixel, true);
}
else
{
@@ -222,14 +246,14 @@ VclPtr<VirtualDevice> VDevBuffer::alloc(OutputDevice& rOutDev, const Size& rSize
}
// remember allocated buffer
- maUsedBuffers.emplace_back(pRetval, bTransparent);
+ maUsedBuffers.emplace_back(pRetval);
return pRetval;
}
void VDevBuffer::free(VirtualDevice& rDevice)
{
- ::osl::MutexGuard aGuard(m_aMutex);
+ std::unique_lock aGuard(m_aMutex);
const auto aUsedFound
= std::find_if(maUsedBuffers.begin(), maUsedBuffers.end(),
[&rDevice](const Entry& el) { return el.buf == &rDevice; });
@@ -247,7 +271,7 @@ void VDevBuffer::free(VirtualDevice& rDevice)
void VDevBuffer::Invoke()
{
- ::osl::MutexGuard aGuard(m_aMutex);
+ std::unique_lock aGuard(m_aMutex);
while (!maFreeBuffers.empty())
{
@@ -257,63 +281,138 @@ void VDevBuffer::Invoke()
maFreeBuffers.pop_back();
}
}
+
+#ifdef SPEED_COMPARE
+void doSpeedCompare(double fTrans, const Bitmap& rContent, const tools::Rectangle& rDestPixel,
+ OutputDevice& rOutDev)
+{
+ const int nAvInd(500);
+ static double fFactors[nAvInd];
+ static int nIndex(nAvInd + 1);
+ static int nRepeat(5);
+ static int nWorseTotal(0);
+ static int nBetterTotal(0);
+ int a(0);
+
+ const Size aSizePixel(rDestPixel.GetSize());
+
+ // init statics
+ if (nIndex > nAvInd)
+ {
+ for (a = 0; a < nAvInd; a++)
+ fFactors[a] = 1.0;
+ nIndex = 0;
+ }
+
+ // get start time
+ const sal_uInt64 nTimeA(tools::Time::GetSystemTicks());
+
+ // loop nRepeat times to get somewhat better timings, else
+ // numbers are pretty small
+ for (a = 0; a < nRepeat; a++)
+ {
+ // "Former" method using a temporary AlphaMask & DrawBitmapEx
+ sal_uInt8 nMaskValue(static_cast<sal_uInt8>(basegfx::fround(fTrans * 255.0)));
+ const AlphaMask aAlphaMask(aSizePixel, &nMaskValue);
+ rOutDev.DrawBitmapEx(rDestPixel.TopLeft(), BitmapEx(rContent, aAlphaMask));
+ }
+
+ // get intermediate time
+ const sal_uInt64 nTimeB(tools::Time::GetSystemTicks());
+
+ // loop nRepeat times
+ for (a = 0; a < nRepeat; a++)
+ {
+ // New method using DrawTransformedBitmapEx & fTrans directly
+ rOutDev.DrawTransformedBitmapEx(basegfx::utils::createScaleTranslateB2DHomMatrix(
+ aSizePixel.Width(), aSizePixel.Height(),
+ rDestPixel.TopLeft().X(), rDestPixel.TopLeft().Y()),
+ BitmapEx(rContent), 1 - fTrans);
+ }
+
+ // get end time
+ const sal_uInt64 nTimeC(tools::Time::GetSystemTicks());
+
+ // calculate deltas
+ const sal_uInt64 nTimeFormer(nTimeB - nTimeA);
+ const sal_uInt64 nTimeNew(nTimeC - nTimeB);
+
+ // compare & note down
+ if (nTimeFormer != nTimeNew && 0 != nTimeFormer && 0 != nTimeNew)
+ {
+ if ((nTimeFormer < 10 || nTimeNew < 10) && nRepeat < 500)
+ {
+ nRepeat += 1;
+ SAL_INFO("drawinglayer.processor2d", "Increment nRepeat to " << nRepeat);
+ return;
+ }
+
+ const double fNewFactor((double)nTimeFormer / nTimeNew);
+ fFactors[nIndex % nAvInd] = fNewFactor;
+ nIndex++;
+ double fAverage(0.0);
+ {
+ for (a = 0; a < nAvInd; a++)
+ fAverage += fFactors[a];
+ fAverage /= nAvInd;
+ }
+ if (fNewFactor < 1.0)
+ nWorseTotal++;
+ else
+ nBetterTotal++;
+
+ char buf[300];
+ sprintf(buf,
+ "Former: %ld New: %ld It got %s (factor %f) (av. last %d Former/New is %f, "
+ "WorseTotal: %d, BetterTotal: %d)",
+ nTimeFormer, nTimeNew, fNewFactor < 1.0 ? "WORSE" : "BETTER",
+ fNewFactor < 1.0 ? 1.0 / fNewFactor : fNewFactor, nAvInd, fAverage, nWorseTotal,
+ nBetterTotal);
+ SAL_INFO("drawinglayer.processor2d", buf);
+ }
+}
+#endif
}
// support for rendering Bitmap and BitmapEx contents
-
namespace drawinglayer
{
-// static global VDev buffer for the VclProcessor2D's (VclMetafileProcessor2D and VclPixelProcessor2D)
+// static global VDev buffer for VclProcessor2D/VclPixelProcessor2D
VDevBuffer& getVDevBuffer()
{
// secure global instance with Vcl's safe destroyer of external (seen by
// library base) stuff, the remembered VDevs need to be deleted before
// Vcl's deinit
- static vcl::DeleteOnDeinit<VDevBuffer> aVDevBuffer(new VDevBuffer());
+ static vcl::DeleteOnDeinit<VDevBuffer> aVDevBuffer{};
return *aVDevBuffer.get();
}
-impBufferDevice::impBufferDevice(OutputDevice& rOutDev, const basegfx::B2DRange& rRange,
- bool bContentTransparent)
+impBufferDevice::impBufferDevice(OutputDevice& rOutDev, const basegfx::B2DRange& rRange)
: mrOutDev(rOutDev)
, mpContent(nullptr)
- , mpMask(nullptr)
, mpAlpha(nullptr)
- , mbContentTransparent(bContentTransparent)
{
basegfx::B2DRange aRangePixel(rRange);
aRangePixel.transform(mrOutDev.GetViewTransformation());
- const ::tools::Rectangle aRectPixel(static_cast<sal_Int32>(floor(aRangePixel.getMinX())),
- static_cast<sal_Int32>(floor(aRangePixel.getMinY())),
- static_cast<sal_Int32>(ceil(aRangePixel.getMaxX())),
- static_cast<sal_Int32>(ceil(aRangePixel.getMaxY())));
- const Point aEmptyPoint;
- maDestPixel = ::tools::Rectangle(aEmptyPoint, mrOutDev.GetOutputSizePixel());
- maDestPixel.Intersection(aRectPixel);
+ maDestPixel = tools::Rectangle(floor(aRangePixel.getMinX()), floor(aRangePixel.getMinY()),
+ ceil(aRangePixel.getMaxX()), ceil(aRangePixel.getMaxY()));
+ maDestPixel.Intersection(tools::Rectangle{ Point{}, mrOutDev.GetOutputSizePixel() });
if (!isVisible())
return;
-#ifdef IOS
- // Exact mechanism unknown, but for some reason SmartArt
- // rendering, especially shadows, is broken on iOS unless
- // we pass 'true' here. Are virtual devices always de
- // facto cleared when created on other platforms?
- mpContent
- = getVDevBuffer().alloc(mrOutDev, maDestPixel.GetSize(), true, false, bContentTransparent);
-#else
- mpContent
- = getVDevBuffer().alloc(mrOutDev, maDestPixel.GetSize(), false, false, bContentTransparent);
-#endif
+ mpContent = getVDevBuffer().alloc(mrOutDev, maDestPixel.GetSize());
// #i93485# assert when copying from window to VDev is used
SAL_WARN_IF(
mrOutDev.GetOutDevType() == OUTDEV_WINDOW, "drawinglayer",
"impBufferDevice render helper: Copying from Window to VDev, this should be avoided (!)");
+ // initialize buffer by blitting content of source to prepare for
+ // transparence/ copying back
const bool bWasEnabledSrc(mrOutDev.IsMapModeEnabled());
mrOutDev.EnableMapMode(false);
- mpContent->DrawOutDev(aEmptyPoint, maDestPixel.GetSize(), maDestPixel.TopLeft(),
+ mpContent->DrawOutDev(Point(), maDestPixel.GetSize(), maDestPixel.TopLeft(),
maDestPixel.GetSize(), mrOutDev);
mrOutDev.EnableMapMode(bWasEnabledSrc);
@@ -338,11 +437,6 @@ impBufferDevice::~impBufferDevice()
getVDevBuffer().free(*mpContent);
}
- if (mpMask)
- {
- getVDevBuffer().free(*mpMask);
- }
-
if (mpAlpha)
{
getVDevBuffer().free(*mpAlpha);
@@ -357,23 +451,18 @@ void impBufferDevice::paint(double fTrans)
const Point aEmptyPoint;
const Size aSizePixel(maDestPixel.GetSize());
const bool bWasEnabledDst(mrOutDev.IsMapModeEnabled());
-#ifdef DBG_UTIL
- static bool bDoSaveForVisualControl(false); // loplugin:constvars:ignore
-#endif
mrOutDev.EnableMapMode(false);
mpContent->EnableMapMode(false);
#ifdef DBG_UTIL
- if (bDoSaveForVisualControl)
+ // VCL_DUMP_BMP_PATH should be like C:/path/ or ~/path/
+ static bool bDoSaveForVisualControl(false); // loplugin:constvars:ignore
+ static const OUString sDumpPath(OUString::createFromAscii(std::getenv("VCL_DUMP_BMP_PATH")));
+
+ if (!sDumpPath.isEmpty() && bDoSaveForVisualControl)
{
- SvFileStream aNew(
-#ifdef _WIN32
- "c:\\content.bmp",
-#else
- "~/content.bmp",
-#endif
- StreamMode::WRITE | StreamMode::TRUNC);
+ SvFileStream aNew(sDumpPath + "content.bmp", StreamMode::WRITE | StreamMode::TRUNC);
Bitmap aContent(mpContent->GetBitmap(aEmptyPoint, aSizePixel));
WriteDIB(aContent, aNew, false, true);
}
@@ -387,67 +476,87 @@ void impBufferDevice::paint(double fTrans)
{
mpAlpha->EnableMapMode(false);
AlphaMask aAlphaMask(mpAlpha->GetBitmap(aEmptyPoint, aSizePixel));
+ aAlphaMask.Invert(); // convert transparency to alpha
#ifdef DBG_UTIL
- if (bDoSaveForVisualControl)
+ if (!sDumpPath.isEmpty() && bDoSaveForVisualControl)
{
- SvFileStream aNew(
-#ifdef _WIN32
- "c:\\transparence.bmp",
-#else
- "~/transparence.bmp",
-#endif
- StreamMode::WRITE | StreamMode::TRUNC);
+ SvFileStream aNew(sDumpPath + "transparence.bmp",
+ StreamMode::WRITE | StreamMode::TRUNC);
WriteDIB(aAlphaMask.GetBitmap(), aNew, false, true);
}
#endif
- BitmapEx aContent(mpContent->GetBitmapEx(aEmptyPoint, aSizePixel));
- if (mbContentTransparent)
- aAlphaMask.BlendWith(aContent.GetAlpha());
- mrOutDev.DrawBitmapEx(maDestPixel.TopLeft(), BitmapEx(aContent.GetBitmap(), aAlphaMask));
+ Bitmap aContent(mpContent->GetBitmap(aEmptyPoint, aSizePixel));
+ mrOutDev.DrawBitmapEx(maDestPixel.TopLeft(), BitmapEx(aContent, aAlphaMask));
}
- else if (mpMask)
+ else if (0.0 != fTrans)
{
- mpMask->EnableMapMode(false);
- const Bitmap aMask(mpMask->GetBitmap(aEmptyPoint, aSizePixel));
+ const Bitmap aContent(mpContent->GetBitmap(aEmptyPoint, aSizePixel));
-#ifdef DBG_UTIL
- if (bDoSaveForVisualControl)
- {
- SvFileStream aNew(
-#ifdef _WIN32
- "c:\\mask.bmp",
-#else
- "~/mask.bmp",
-#endif
- StreamMode::WRITE | StreamMode::TRUNC);
- WriteDIB(aMask, aNew, false, true);
- }
-#endif
+#ifdef SPEED_COMPARE
+ static bool bCompareFormerAndNewTimings(true);
- if (mbContentTransparent)
+ if (bCompareFormerAndNewTimings)
{
- BitmapEx aContent(mpContent->GetBitmapEx(aEmptyPoint, aSizePixel));
- AlphaMask aAlpha(aContent.GetAlpha());
- aAlpha.BlendWith(aMask);
- mrOutDev.DrawBitmapEx(maDestPixel.TopLeft(), BitmapEx(aContent.GetBitmap(), aAlpha));
+ doSpeedCompare(fTrans, aContent, maDestPixel, mrOutDev);
}
else
+#endif
+ // Note: this extra scope is needed due to 'clang plugin indentation'. It complains
+ // that lines 494 and (now) 539 are 'statement mis-aligned compared to neighbours'.
+ // That is true if SPEED_COMPARE is not defined. Not nice, but have to fix this.
{
- Bitmap aContent(mpContent->GetBitmap(aEmptyPoint, aSizePixel));
- mrOutDev.DrawBitmapEx(maDestPixel.TopLeft(), BitmapEx(aContent, aMask));
+ // For the case we have a unified transparency value there is a former
+ // and new method to paint that which can be used. To decide on measurements,
+ // I added 'doSpeedCompare' above which can be activated by defining
+ // SPEED_COMPARE at the top of this file.
+ // I added the used Testdoc: blurplay3.odg as
+ // https://bugs.documentfoundation.org/attachment.cgi?id=182463
+ // I did measure on
+ //
+ // Linux Dbg:
+ // Former: 21 New: 32 It got WORSE (factor 1.523810) (av. last 500 Former/New is 0.968533, WorseTotal: 515, BetterTotal: 934)
+ //
+ // Linux Pro:
+ // Former: 27 New: 44 It got WORSE (factor 1.629630) (av. last 500 Former/New is 0.923256, WorseTotal: 433, BetterTotal: 337)
+ //
+ // Win Dbg:
+ // Former: 21 New: 78 It got WORSE (factor 3.714286) (av. last 500 Former/New is 1.007176, WorseTotal: 85, BetterTotal: 1428)
+ //
+ // Win Pro:
+ // Former: 3 New: 4 It got WORSE (factor 1.333333) (av. last 500 Former/New is 1.054167, WorseTotal: 143, BetterTotal: 3909)
+ //
+ // Note: I am aware that the Dbg are of limited usefulness, but include them here
+ // for reference.
+ //
+ // The important part is "av. last 500 Former/New is %ld" which describes the averaged factor from Former/New
+ // over the last 500 measurements. When < 1.0 Former is better (Linux), > 1.0 (Win) New is better. Since the
+ // factor on Win is still close to 1.0 what means we lose nearly nothing and Linux Former is better, I will
+ // use Former for now.
+ //
+ // To easily allow to change this (maybe system-dependent) I add a static switch here,
+ // also for eventually experimenting (hint: can be changed in the debugger).
+ static bool bUseNew(false);
+
+ if (bUseNew)
+ {
+ // New method using DrawTransformedBitmapEx & fTrans directly
+ mrOutDev.DrawTransformedBitmapEx(basegfx::utils::createScaleTranslateB2DHomMatrix(
+ aSizePixel.Width(), aSizePixel.Height(),
+ maDestPixel.TopLeft().X(),
+ maDestPixel.TopLeft().Y()),
+ BitmapEx(aContent), 1 - fTrans);
+ }
+ else
+ {
+ // "Former" method using a temporary AlphaMask & DrawBitmapEx
+ sal_uInt8 nMaskValue(static_cast<sal_uInt8>(basegfx::fround(fTrans * 255.0)));
+ const AlphaMask aAlphaMask(aSizePixel, &nMaskValue);
+ mrOutDev.DrawBitmapEx(maDestPixel.TopLeft(), BitmapEx(aContent, aAlphaMask));
+ }
}
}
- else if (0.0 != fTrans)
- {
- sal_uInt8 nMaskValue(static_cast<sal_uInt8>(basegfx::fround(fTrans * 255.0)));
- AlphaMask aAlphaMask(aSizePixel, &nMaskValue);
- BitmapEx aContent(mpContent->GetBitmapEx(aEmptyPoint, aSizePixel));
- if (mbContentTransparent)
- aAlphaMask.BlendWith(aContent.GetAlpha());
- mrOutDev.DrawBitmapEx(maDestPixel.TopLeft(), BitmapEx(aContent.GetBitmap(), aAlphaMask));
- }
else
{
mrOutDev.DrawOutDev(maDestPixel.TopLeft(), aSizePixel, aEmptyPoint, aSizePixel, *mpContent);
@@ -464,28 +573,13 @@ VirtualDevice& impBufferDevice::getContent()
return *mpContent;
}
-VirtualDevice& impBufferDevice::getMask()
-{
- SAL_WARN_IF(!mpContent, "drawinglayer",
- "impBufferDevice: No content, check isVisible() before accessing (!)");
- if (!mpMask)
- {
- mpMask = getVDevBuffer().alloc(mrOutDev, maDestPixel.GetSize(), true, true, false);
- mpMask->SetMapMode(mpContent->GetMapMode());
-
- // do NOT copy AA flag for mask!
- }
-
- return *mpMask;
-}
-
VirtualDevice& impBufferDevice::getTransparence()
{
SAL_WARN_IF(!mpContent, "drawinglayer",
"impBufferDevice: No content, check isVisible() before accessing (!)");
if (!mpAlpha)
{
- mpAlpha = getVDevBuffer().alloc(mrOutDev, maDestPixel.GetSize(), true, false, false);
+ mpAlpha = getVDevBuffer().alloc(mrOutDev, maDestPixel.GetSize());
mpAlpha->SetMapMode(mpContent->GetMapMode());
// copy AA flag for new target; masking needs to be smooth