xref: /AOO41X/main/drawinglayer/source/processor2d/vclhelperbufferdevice.cxx (revision 47148b3bc50811ceb41802e4cc50a5db21535900)
1464702f4SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3464702f4SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4464702f4SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5464702f4SAndrew Rist  * distributed with this work for additional information
6464702f4SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7464702f4SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8464702f4SAndrew Rist  * "License"); you may not use this file except in compliance
9464702f4SAndrew Rist  * with the License.  You may obtain a copy of the License at
10cdf0e10cSrcweir  *
11464702f4SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir  *
13464702f4SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14464702f4SAndrew Rist  * software distributed under the License is distributed on an
15464702f4SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16464702f4SAndrew Rist  * KIND, either express or implied.  See the License for the
17464702f4SAndrew Rist  * specific language governing permissions and limitations
18464702f4SAndrew Rist  * under the License.
19cdf0e10cSrcweir  *
20464702f4SAndrew Rist  *************************************************************/
21464702f4SAndrew Rist 
22cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
23cdf0e10cSrcweir #include "precompiled_drawinglayer.hxx"
24cdf0e10cSrcweir 
25cdf0e10cSrcweir #include <vclhelperbufferdevice.hxx>
26cdf0e10cSrcweir #include <basegfx/range/b2drange.hxx>
27cdf0e10cSrcweir #include <vcl/bitmapex.hxx>
28cdf0e10cSrcweir #include <basegfx/matrix/b2dhommatrix.hxx>
29cdf0e10cSrcweir #include <tools/stream.hxx>
30ce37d08fSArmin Le Grand #include <vcl/timer.hxx>
31ce37d08fSArmin Le Grand #include <comphelper/broadcasthelper.hxx>
3233a1c393SArmin Le Grand #include <vcl/lazydelete.hxx>
33*45fd3b9aSArmin Le Grand #include <vcl/dibtools.hxx>
34ce37d08fSArmin Le Grand 
35ce37d08fSArmin Le Grand //////////////////////////////////////////////////////////////////////////////
36ce37d08fSArmin Le Grand // buffered VDev usage
37ce37d08fSArmin Le Grand 
38ce37d08fSArmin Le Grand namespace
39ce37d08fSArmin Le Grand {
40ce37d08fSArmin Le Grand     typedef ::std::vector< VirtualDevice* > aBuffers;
41ce37d08fSArmin Le Grand 
42ce37d08fSArmin Le Grand     class VDevBuffer : public Timer, protected comphelper::OBaseMutex
43ce37d08fSArmin Le Grand     {
44ce37d08fSArmin Le Grand     private:
4556a68a31SArmin Le Grand         // available buffers
4656a68a31SArmin Le Grand         aBuffers            maFreeBuffers;
4756a68a31SArmin Le Grand 
4856a68a31SArmin Le Grand         // allocated/used buffers (remembered to allow deleteing them in destructor)
4956a68a31SArmin Le Grand         aBuffers            maUsedBuffers;
50ce37d08fSArmin Le Grand 
51ce37d08fSArmin Le Grand     public:
52ce37d08fSArmin Le Grand         VDevBuffer();
53ce37d08fSArmin Le Grand         virtual ~VDevBuffer();
54ce37d08fSArmin Le Grand 
55ce37d08fSArmin Le Grand         VirtualDevice* alloc(OutputDevice& rOutDev, const Size& rSizePixel, bool bClear, bool bMono);
56ce37d08fSArmin Le Grand         void free(VirtualDevice& rDevice);
57ce37d08fSArmin Le Grand 
58ce37d08fSArmin Le Grand         // Timer virtuals
59ce37d08fSArmin Le Grand         virtual void Timeout();
60ce37d08fSArmin Le Grand     };
61ce37d08fSArmin Le Grand 
VDevBuffer()62ce37d08fSArmin Le Grand     VDevBuffer::VDevBuffer()
63ce37d08fSArmin Le Grand     :   Timer(),
6456a68a31SArmin Le Grand         maFreeBuffers(),
6556a68a31SArmin Le Grand         maUsedBuffers()
66ce37d08fSArmin Le Grand     {
67ce37d08fSArmin Le Grand         SetTimeout(10L * 1000L); // ten seconds
68ce37d08fSArmin Le Grand     }
69ce37d08fSArmin Le Grand 
~VDevBuffer()70ce37d08fSArmin Le Grand     VDevBuffer::~VDevBuffer()
71ce37d08fSArmin Le Grand     {
72ce37d08fSArmin Le Grand         ::osl::MutexGuard aGuard(m_aMutex);
73ce37d08fSArmin Le Grand         Stop();
74ce37d08fSArmin Le Grand 
7556a68a31SArmin Le Grand         while(!maFreeBuffers.empty())
76ce37d08fSArmin Le Grand         {
7756a68a31SArmin Le Grand             delete *(maFreeBuffers.end() - 1);
7856a68a31SArmin Le Grand             maFreeBuffers.pop_back();
7956a68a31SArmin Le Grand         }
8056a68a31SArmin Le Grand 
8156a68a31SArmin Le Grand         while(!maUsedBuffers.empty())
8256a68a31SArmin Le Grand         {
8356a68a31SArmin Le Grand             delete *(maUsedBuffers.end() - 1);
8456a68a31SArmin Le Grand             maUsedBuffers.pop_back();
85ce37d08fSArmin Le Grand         }
86ce37d08fSArmin Le Grand     }
87ce37d08fSArmin Le Grand 
alloc(OutputDevice & rOutDev,const Size & rSizePixel,bool bClear,bool bMono)88ce37d08fSArmin Le Grand     VirtualDevice* VDevBuffer::alloc(OutputDevice& rOutDev, const Size& rSizePixel, bool bClear, bool bMono)
89ce37d08fSArmin Le Grand     {
90ce37d08fSArmin Le Grand         ::osl::MutexGuard aGuard(m_aMutex);
91ce37d08fSArmin Le Grand         VirtualDevice* pRetval = 0;
92ce37d08fSArmin Le Grand 
9356a68a31SArmin Le Grand         if(!maFreeBuffers.empty())
94ce37d08fSArmin Le Grand         {
95ce37d08fSArmin Le Grand             bool bOkay(false);
9656a68a31SArmin Le Grand             aBuffers::iterator aFound(maFreeBuffers.end());
97ce37d08fSArmin Le Grand 
9856a68a31SArmin Le Grand             for(aBuffers::iterator a(maFreeBuffers.begin()); a != maFreeBuffers.end(); a++)
99ce37d08fSArmin Le Grand             {
100ce37d08fSArmin Le Grand                 OSL_ENSURE(*a, "Empty pointer in VDevBuffer (!)");
101ce37d08fSArmin Le Grand 
102ce37d08fSArmin Le Grand                 if((bMono && 1 == (*a)->GetBitCount()) || (!bMono && (*a)->GetBitCount() > 1))
103ce37d08fSArmin Le Grand                 {
104ce37d08fSArmin Le Grand                     // candidate is valid due to bit depth
10556a68a31SArmin Le Grand                     if(aFound != maFreeBuffers.end())
106ce37d08fSArmin Le Grand                     {
107ce37d08fSArmin Le Grand                         // already found
108ce37d08fSArmin Le Grand                         if(bOkay)
109ce37d08fSArmin Le Grand                         {
110ce37d08fSArmin Le Grand                             // found is valid
111ce37d08fSArmin Le Grand                             const bool bCandidateOkay((*a)->GetOutputWidthPixel() >= rSizePixel.getWidth() && (*a)->GetOutputHeightPixel() >= rSizePixel.getHeight());
112ce37d08fSArmin Le Grand 
113ce37d08fSArmin Le Grand                             if(bCandidateOkay)
114ce37d08fSArmin Le Grand                             {
115ce37d08fSArmin Le Grand                                 // found and candidate are valid
116ce37d08fSArmin Le Grand                                 const sal_uLong aSquare((*aFound)->GetOutputWidthPixel() * (*aFound)->GetOutputHeightPixel());
117ce37d08fSArmin Le Grand                                 const sal_uLong aCandidateSquare((*a)->GetOutputWidthPixel() * (*a)->GetOutputHeightPixel());
118ce37d08fSArmin Le Grand 
119ce37d08fSArmin Le Grand                                 if(aCandidateSquare < aSquare)
120ce37d08fSArmin Le Grand                                 {
121ce37d08fSArmin Le Grand                                     // candidate is valid and smaller, use it
122ce37d08fSArmin Le Grand                                     aFound = a;
123ce37d08fSArmin Le Grand                                 }
124ce37d08fSArmin Le Grand                             }
125ce37d08fSArmin Le Grand                             else
126ce37d08fSArmin Le Grand                             {
127ce37d08fSArmin Le Grand                                 // found is valid, candidate is not. Keep found
128ce37d08fSArmin Le Grand                             }
129ce37d08fSArmin Le Grand                         }
130ce37d08fSArmin Le Grand                         else
131ce37d08fSArmin Le Grand                         {
132ce37d08fSArmin Le Grand                             // found is invalid, use candidate
133ce37d08fSArmin Le Grand                             aFound = a;
134ce37d08fSArmin Le Grand                             bOkay = (*aFound)->GetOutputWidthPixel() >= rSizePixel.getWidth() && (*aFound)->GetOutputHeightPixel() >= rSizePixel.getHeight();
135ce37d08fSArmin Le Grand                         }
136ce37d08fSArmin Le Grand                     }
137ce37d08fSArmin Le Grand                     else
138ce37d08fSArmin Le Grand                     {
139ce37d08fSArmin Le Grand                         // none yet, use candidate
140ce37d08fSArmin Le Grand                         aFound = a;
141ce37d08fSArmin Le Grand                         bOkay = (*aFound)->GetOutputWidthPixel() >= rSizePixel.getWidth() && (*aFound)->GetOutputHeightPixel() >= rSizePixel.getHeight();
142ce37d08fSArmin Le Grand                     }
143ce37d08fSArmin Le Grand                 }
144ce37d08fSArmin Le Grand             }
145ce37d08fSArmin Le Grand 
14656a68a31SArmin Le Grand             if(aFound != maFreeBuffers.end())
147ce37d08fSArmin Le Grand             {
148ce37d08fSArmin Le Grand                 pRetval = *aFound;
14956a68a31SArmin Le Grand                 maFreeBuffers.erase(aFound);
150ce37d08fSArmin Le Grand 
151ce37d08fSArmin Le Grand                 if(bOkay)
152ce37d08fSArmin Le Grand                 {
153ce37d08fSArmin Le Grand                     if(bClear)
154ce37d08fSArmin Le Grand                     {
155ce37d08fSArmin Le Grand                         pRetval->Erase(Rectangle(0, 0, rSizePixel.getWidth(), rSizePixel.getHeight()));
156ce37d08fSArmin Le Grand                     }
157ce37d08fSArmin Le Grand                 }
158ce37d08fSArmin Le Grand                 else
159ce37d08fSArmin Le Grand                 {
160ce37d08fSArmin Le Grand                     pRetval->SetOutputSizePixel(rSizePixel, bClear);
161ce37d08fSArmin Le Grand                 }
162ce37d08fSArmin Le Grand             }
163ce37d08fSArmin Le Grand         }
164ce37d08fSArmin Le Grand 
165ce37d08fSArmin Le Grand         // no success yet, create new buffer
166ce37d08fSArmin Le Grand         if(!pRetval)
167ce37d08fSArmin Le Grand         {
168ce37d08fSArmin Le Grand             pRetval = (bMono) ? new VirtualDevice(rOutDev, 1) : new VirtualDevice(rOutDev);
169ce37d08fSArmin Le Grand             pRetval->SetOutputSizePixel(rSizePixel, bClear);
170ce37d08fSArmin Le Grand         }
171ce37d08fSArmin Le Grand         else
172ce37d08fSArmin Le Grand         {
173ce37d08fSArmin Le Grand             // reused, reset some values
174ce37d08fSArmin Le Grand             pRetval->SetMapMode();
175ce37d08fSArmin Le Grand         }
176ce37d08fSArmin Le Grand 
17756a68a31SArmin Le Grand         // remember allocated buffer
17856a68a31SArmin Le Grand         maUsedBuffers.push_back(pRetval);
17956a68a31SArmin Le Grand 
180ce37d08fSArmin Le Grand         return pRetval;
181ce37d08fSArmin Le Grand     }
182ce37d08fSArmin Le Grand 
free(VirtualDevice & rDevice)183ce37d08fSArmin Le Grand     void VDevBuffer::free(VirtualDevice& rDevice)
184ce37d08fSArmin Le Grand     {
185ce37d08fSArmin Le Grand         ::osl::MutexGuard aGuard(m_aMutex);
18656a68a31SArmin Le Grand         const aBuffers::iterator aUsedFound(::std::find(maUsedBuffers.begin(), maUsedBuffers.end(), &rDevice));
18756a68a31SArmin Le Grand         OSL_ENSURE(aUsedFound != maUsedBuffers.end(), "OOps, non-registered buffer freed (!)");
18856a68a31SArmin Le Grand 
18956a68a31SArmin Le Grand         maUsedBuffers.erase(aUsedFound);
19056a68a31SArmin Le Grand         maFreeBuffers.push_back(&rDevice);
191ce37d08fSArmin Le Grand         Start();
192ce37d08fSArmin Le Grand     }
193ce37d08fSArmin Le Grand 
Timeout()194ce37d08fSArmin Le Grand     void VDevBuffer::Timeout()
195ce37d08fSArmin Le Grand     {
196ce37d08fSArmin Le Grand         ::osl::MutexGuard aGuard(m_aMutex);
197ce37d08fSArmin Le Grand 
19856a68a31SArmin Le Grand         while(!maFreeBuffers.empty())
199ce37d08fSArmin Le Grand         {
20056a68a31SArmin Le Grand             delete *(maFreeBuffers.end() - 1);
20156a68a31SArmin Le Grand             maFreeBuffers.pop_back();
202ce37d08fSArmin Le Grand         }
203ce37d08fSArmin Le Grand     }
204ce37d08fSArmin Le Grand }
205cdf0e10cSrcweir 
206cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
207cdf0e10cSrcweir // support for rendering Bitmap and BitmapEx contents
208cdf0e10cSrcweir 
209cdf0e10cSrcweir namespace drawinglayer
210cdf0e10cSrcweir {
211ce37d08fSArmin Le Grand     // static global VDev buffer for the VclProcessor2D's (VclMetafileProcessor2D and VclPixelProcessor2D)
getVDevBuffer()21233a1c393SArmin Le Grand     VDevBuffer& getVDevBuffer()
21333a1c393SArmin Le Grand     {
21433a1c393SArmin Le Grand         // secure global instance with Vcl's safe desroyer of external (seen by
21533a1c393SArmin Le Grand         // library base) stuff, the remembered VDevs need to be deleted before
21633a1c393SArmin Le Grand         // Vcl's deinit
21733a1c393SArmin Le Grand         static vcl::DeleteOnDeinit< VDevBuffer > aVDevBuffer(new VDevBuffer());
21833a1c393SArmin Le Grand         return *aVDevBuffer.get();
21933a1c393SArmin Le Grand     }
220ce37d08fSArmin Le Grand 
impBufferDevice(OutputDevice & rOutDev,const basegfx::B2DRange & rRange,bool bAddOffsetToMapping)221cdf0e10cSrcweir     impBufferDevice::impBufferDevice(
222cdf0e10cSrcweir         OutputDevice& rOutDev,
223cdf0e10cSrcweir         const basegfx::B2DRange& rRange,
224cdf0e10cSrcweir         bool bAddOffsetToMapping)
225cdf0e10cSrcweir     :   mrOutDev(rOutDev),
226ce37d08fSArmin Le Grand         mpContent(0),
227ce37d08fSArmin Le Grand         mpMask(0),
228ce37d08fSArmin Le Grand         mpAlpha(0)
229cdf0e10cSrcweir     {
230cdf0e10cSrcweir         basegfx::B2DRange aRangePixel(rRange);
231ce37d08fSArmin Le Grand         aRangePixel.transform(mrOutDev.GetViewTransformation());
232cdf0e10cSrcweir         const Rectangle aRectPixel(
233cdf0e10cSrcweir             (sal_Int32)floor(aRangePixel.getMinX()), (sal_Int32)floor(aRangePixel.getMinY()),
234cdf0e10cSrcweir             (sal_Int32)ceil(aRangePixel.getMaxX()), (sal_Int32)ceil(aRangePixel.getMaxY()));
235cdf0e10cSrcweir         const Point aEmptyPoint;
236ce37d08fSArmin Le Grand         maDestPixel = Rectangle(aEmptyPoint, mrOutDev.GetOutputSizePixel());
237cdf0e10cSrcweir         maDestPixel.Intersection(aRectPixel);
238cdf0e10cSrcweir 
239cdf0e10cSrcweir         if(isVisible())
240cdf0e10cSrcweir         {
24133a1c393SArmin Le Grand             mpContent = getVDevBuffer().alloc(mrOutDev, maDestPixel.GetSize(), false, false);
242cdf0e10cSrcweir 
243cdf0e10cSrcweir             // #i93485# assert when copying from window to VDev is used
244ce37d08fSArmin Le Grand             OSL_ENSURE(mrOutDev.GetOutDevType() != OUTDEV_WINDOW,
245cdf0e10cSrcweir                 "impBufferDevice render helper: Copying from Window to VDev, this should be avoided (!)");
246cdf0e10cSrcweir 
247ce37d08fSArmin Le Grand             const bool bWasEnabledSrc(mrOutDev.IsMapModeEnabled());
248ce37d08fSArmin Le Grand             mrOutDev.EnableMapMode(false);
249ce37d08fSArmin Le Grand             mpContent->DrawOutDev(aEmptyPoint, maDestPixel.GetSize(), maDestPixel.TopLeft(), maDestPixel.GetSize(), mrOutDev);
250ce37d08fSArmin Le Grand             mrOutDev.EnableMapMode(bWasEnabledSrc);
251cdf0e10cSrcweir 
252ce37d08fSArmin Le Grand             MapMode aNewMapMode(mrOutDev.GetMapMode());
253cdf0e10cSrcweir 
254cdf0e10cSrcweir             if(bAddOffsetToMapping)
255cdf0e10cSrcweir             {
256ce37d08fSArmin Le Grand                 const Point aLogicTopLeft(mrOutDev.PixelToLogic(maDestPixel.TopLeft()));
257cdf0e10cSrcweir                 aNewMapMode.SetOrigin(Point(-aLogicTopLeft.X(), -aLogicTopLeft.Y()));
258cdf0e10cSrcweir             }
259cdf0e10cSrcweir 
260ce37d08fSArmin Le Grand             mpContent->SetMapMode(aNewMapMode);
261cdf0e10cSrcweir 
262cdf0e10cSrcweir             // copy AA flag for new target
263ce37d08fSArmin Le Grand             mpContent->SetAntialiasing(mrOutDev.GetAntialiasing());
264cdf0e10cSrcweir         }
265cdf0e10cSrcweir     }
266cdf0e10cSrcweir 
~impBufferDevice()267cdf0e10cSrcweir     impBufferDevice::~impBufferDevice()
268cdf0e10cSrcweir     {
269ce37d08fSArmin Le Grand         if(mpContent)
270ce37d08fSArmin Le Grand         {
27133a1c393SArmin Le Grand             getVDevBuffer().free(*mpContent);
272ce37d08fSArmin Le Grand         }
273ce37d08fSArmin Le Grand 
274ce37d08fSArmin Le Grand         if(mpMask)
275ce37d08fSArmin Le Grand         {
27633a1c393SArmin Le Grand             getVDevBuffer().free(*mpMask);
277ce37d08fSArmin Le Grand         }
278ce37d08fSArmin Le Grand 
279ce37d08fSArmin Le Grand         if(mpAlpha)
280ce37d08fSArmin Le Grand         {
28133a1c393SArmin Le Grand             getVDevBuffer().free(*mpAlpha);
282ce37d08fSArmin Le Grand         }
283cdf0e10cSrcweir     }
284cdf0e10cSrcweir 
paint(double fTrans)285cdf0e10cSrcweir     void impBufferDevice::paint(double fTrans)
286cdf0e10cSrcweir     {
287ce37d08fSArmin Le Grand         if(isVisible())
288ce37d08fSArmin Le Grand         {
289cdf0e10cSrcweir             const Point aEmptyPoint;
290ce37d08fSArmin Le Grand             const Size aSizePixel(maDestPixel.GetSize());
291cdf0e10cSrcweir             const bool bWasEnabledDst(mrOutDev.IsMapModeEnabled());
292cdf0e10cSrcweir             static bool bDoSaveForVisualControl(false);
293cdf0e10cSrcweir 
294cdf0e10cSrcweir             mrOutDev.EnableMapMode(false);
295ce37d08fSArmin Le Grand             mpContent->EnableMapMode(false);
296ce37d08fSArmin Le Grand             Bitmap aContent(mpContent->GetBitmap(aEmptyPoint, aSizePixel));
297cdf0e10cSrcweir 
298cdf0e10cSrcweir             if(bDoSaveForVisualControl)
299cdf0e10cSrcweir             {
300cdf0e10cSrcweir                 SvFileStream aNew((const String&)String(ByteString( "c:\\content.bmp" ), RTL_TEXTENCODING_UTF8), STREAM_WRITE|STREAM_TRUNC);
301*45fd3b9aSArmin Le Grand                 WriteDIB(aContent, aNew, false, true);
302cdf0e10cSrcweir             }
303cdf0e10cSrcweir 
304cdf0e10cSrcweir             if(mpAlpha)
305cdf0e10cSrcweir             {
306cdf0e10cSrcweir                 mpAlpha->EnableMapMode(false);
307cdf0e10cSrcweir                 const AlphaMask aAlphaMask(mpAlpha->GetBitmap(aEmptyPoint, aSizePixel));
308cdf0e10cSrcweir 
309cdf0e10cSrcweir                 if(bDoSaveForVisualControl)
310cdf0e10cSrcweir                 {
311cdf0e10cSrcweir                     SvFileStream aNew((const String&)String(ByteString( "c:\\transparence.bmp" ), RTL_TEXTENCODING_UTF8), STREAM_WRITE|STREAM_TRUNC);
312*45fd3b9aSArmin Le Grand                     WriteDIB(aAlphaMask.GetBitmap(), aNew, false, true);
313cdf0e10cSrcweir                 }
314cdf0e10cSrcweir 
315cdf0e10cSrcweir                 mrOutDev.DrawBitmapEx(maDestPixel.TopLeft(), BitmapEx(aContent, aAlphaMask));
316cdf0e10cSrcweir             }
317cdf0e10cSrcweir             else if(mpMask)
318cdf0e10cSrcweir             {
319cdf0e10cSrcweir                 mpMask->EnableMapMode(false);
320cdf0e10cSrcweir                 const Bitmap aMask(mpMask->GetBitmap(aEmptyPoint, aSizePixel));
321cdf0e10cSrcweir 
322cdf0e10cSrcweir                 if(bDoSaveForVisualControl)
323cdf0e10cSrcweir                 {
324cdf0e10cSrcweir                     SvFileStream aNew((const String&)String(ByteString( "c:\\mask.bmp" ), RTL_TEXTENCODING_UTF8), STREAM_WRITE|STREAM_TRUNC);
325*45fd3b9aSArmin Le Grand                     WriteDIB(aMask, aNew, false, true);
326cdf0e10cSrcweir                 }
327cdf0e10cSrcweir 
328cdf0e10cSrcweir                 mrOutDev.DrawBitmapEx(maDestPixel.TopLeft(), BitmapEx(aContent, aMask));
329cdf0e10cSrcweir             }
330cdf0e10cSrcweir             else if(0.0 != fTrans)
331cdf0e10cSrcweir             {
332cdf0e10cSrcweir                 sal_uInt8 nMaskValue((sal_uInt8)basegfx::fround(fTrans * 255.0));
333cdf0e10cSrcweir                 const AlphaMask aAlphaMask(aSizePixel, &nMaskValue);
334cdf0e10cSrcweir                 mrOutDev.DrawBitmapEx(maDestPixel.TopLeft(), BitmapEx(aContent, aAlphaMask));
335cdf0e10cSrcweir             }
336cdf0e10cSrcweir             else
337cdf0e10cSrcweir             {
338cdf0e10cSrcweir                 mrOutDev.DrawBitmap(maDestPixel.TopLeft(), aContent);
339cdf0e10cSrcweir             }
340cdf0e10cSrcweir 
341cdf0e10cSrcweir             mrOutDev.EnableMapMode(bWasEnabledDst);
342cdf0e10cSrcweir         }
343ce37d08fSArmin Le Grand     }
344ce37d08fSArmin Le Grand 
getContent()345ce37d08fSArmin Le Grand     VirtualDevice& impBufferDevice::getContent()
346ce37d08fSArmin Le Grand     {
347ce37d08fSArmin Le Grand         OSL_ENSURE(mpContent, "impBufferDevice: No content, check isVisible() before accessing (!)");
348ce37d08fSArmin Le Grand         return *mpContent;
349ce37d08fSArmin Le Grand     }
350cdf0e10cSrcweir 
getMask()351cdf0e10cSrcweir     VirtualDevice& impBufferDevice::getMask()
352cdf0e10cSrcweir     {
353ce37d08fSArmin Le Grand         OSL_ENSURE(mpContent, "impBufferDevice: No content, check isVisible() before accessing (!)");
354cdf0e10cSrcweir         if(!mpMask)
355cdf0e10cSrcweir         {
35633a1c393SArmin Le Grand             mpMask = getVDevBuffer().alloc(mrOutDev, maDestPixel.GetSize(), true, true);
357ce37d08fSArmin Le Grand             mpMask->SetMapMode(mpContent->GetMapMode());
358cdf0e10cSrcweir 
359cdf0e10cSrcweir             // do NOT copy AA flag for mask!
360cdf0e10cSrcweir         }
361cdf0e10cSrcweir 
362cdf0e10cSrcweir         return *mpMask;
363cdf0e10cSrcweir     }
364cdf0e10cSrcweir 
getTransparence()365cdf0e10cSrcweir     VirtualDevice& impBufferDevice::getTransparence()
366cdf0e10cSrcweir     {
367ce37d08fSArmin Le Grand         OSL_ENSURE(mpContent, "impBufferDevice: No content, check isVisible() before accessing (!)");
368cdf0e10cSrcweir         if(!mpAlpha)
369cdf0e10cSrcweir         {
37033a1c393SArmin Le Grand             mpAlpha = getVDevBuffer().alloc(mrOutDev, maDestPixel.GetSize(), true, false);
371ce37d08fSArmin Le Grand             mpAlpha->SetMapMode(mpContent->GetMapMode());
372cdf0e10cSrcweir 
373cdf0e10cSrcweir             // copy AA flag for new target; masking needs to be smooth
374ce37d08fSArmin Le Grand             mpAlpha->SetAntialiasing(mpContent->GetAntialiasing());
375cdf0e10cSrcweir         }
376cdf0e10cSrcweir 
377cdf0e10cSrcweir         return *mpAlpha;
378cdf0e10cSrcweir     }
379cdf0e10cSrcweir } // end of namespace drawinglayer
380cdf0e10cSrcweir 
381cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
382cdf0e10cSrcweir // eof
383