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