xref: /trunk/main/sd/source/ui/slidesorter/view/SlsLayeredDevice.cxx (revision 9816bc0486dd8b95ea2bf0862e1989f2758285c6)
15b190011SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
35b190011SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
45b190011SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
55b190011SAndrew Rist  * distributed with this work for additional information
65b190011SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
75b190011SAndrew Rist  * to you under the Apache License, Version 2.0 (the
85b190011SAndrew Rist  * "License"); you may not use this file except in compliance
95b190011SAndrew Rist  * with the License.  You may obtain a copy of the License at
10cdf0e10cSrcweir  *
115b190011SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir  *
135b190011SAndrew Rist  * Unless required by applicable law or agreed to in writing,
145b190011SAndrew Rist  * software distributed under the License is distributed on an
155b190011SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
165b190011SAndrew Rist  * KIND, either express or implied.  See the License for the
175b190011SAndrew Rist  * specific language governing permissions and limitations
185b190011SAndrew Rist  * under the License.
19cdf0e10cSrcweir  *
205b190011SAndrew Rist  *************************************************************/
215b190011SAndrew Rist 
225b190011SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir #include "precompiled_sd.hxx"
25cdf0e10cSrcweir 
26cdf0e10cSrcweir #include "SlsLayeredDevice.hxx"
27cdf0e10cSrcweir 
28cdf0e10cSrcweir #include <vcl/window.hxx>
29cdf0e10cSrcweir #include <vcl/virdev.hxx>
30cdf0e10cSrcweir 
31cdf0e10cSrcweir #include <boost/bind.hpp>
32cdf0e10cSrcweir #include <boost/function.hpp>
33cdf0e10cSrcweir 
34cdf0e10cSrcweir 
35cdf0e10cSrcweir namespace sd { namespace slidesorter { namespace view {
36cdf0e10cSrcweir 
37cdf0e10cSrcweir namespace {
38cdf0e10cSrcweir static const sal_Int32 gnMaximumLayerCount = 8;
39cdf0e10cSrcweir 
40cdf0e10cSrcweir class LayerInvalidator : public ILayerInvalidator
41cdf0e10cSrcweir {
42cdf0e10cSrcweir public:
LayerInvalidator(const::boost::shared_ptr<LayeredDevice> & rpLayeredDevice,const SharedSdWindow & rpTargetWindow,const int nLayer)43cdf0e10cSrcweir     LayerInvalidator (
44cdf0e10cSrcweir         const ::boost::shared_ptr<LayeredDevice>& rpLayeredDevice,
45cdf0e10cSrcweir         const SharedSdWindow& rpTargetWindow,
46cdf0e10cSrcweir         const int nLayer)
47cdf0e10cSrcweir         : mpLayeredDevice(rpLayeredDevice),
48cdf0e10cSrcweir           mpTargetWindow(rpTargetWindow),
49cdf0e10cSrcweir           mnLayer(nLayer)
50cdf0e10cSrcweir     {
51cdf0e10cSrcweir     }
52cdf0e10cSrcweir 
Invalidate(const Rectangle & rInvalidationBox)53cdf0e10cSrcweir     virtual void Invalidate (const Rectangle& rInvalidationBox)
54cdf0e10cSrcweir     {
55cdf0e10cSrcweir         mpLayeredDevice->Invalidate(rInvalidationBox, mnLayer);
56cdf0e10cSrcweir         mpTargetWindow->Invalidate(rInvalidationBox);
57cdf0e10cSrcweir     }
58cdf0e10cSrcweir 
59cdf0e10cSrcweir private:
60cdf0e10cSrcweir     const ::boost::shared_ptr<LayeredDevice> mpLayeredDevice;
61cdf0e10cSrcweir     SharedSdWindow mpTargetWindow;
62cdf0e10cSrcweir     const int mnLayer;
63cdf0e10cSrcweir };
64cdf0e10cSrcweir 
DeviceCopy(OutputDevice & rTargetDevice,OutputDevice & rSourceDevice,const Rectangle & rBox)65cdf0e10cSrcweir void DeviceCopy (
66cdf0e10cSrcweir     OutputDevice& rTargetDevice,
67cdf0e10cSrcweir     OutputDevice& rSourceDevice,
68cdf0e10cSrcweir     const Rectangle& rBox)
69cdf0e10cSrcweir {
70cdf0e10cSrcweir     rTargetDevice.DrawOutDev(
71cdf0e10cSrcweir         rBox.TopLeft(),
72cdf0e10cSrcweir         rBox.GetSize(),
73cdf0e10cSrcweir         rBox.TopLeft(),
74cdf0e10cSrcweir         rBox.GetSize(),
75cdf0e10cSrcweir         rSourceDevice);
76cdf0e10cSrcweir }
77cdf0e10cSrcweir 
78cdf0e10cSrcweir 
ForAllRectangles(const Region & rRegion,::boost::function<void (const Rectangle &)> aFunction)79cdf0e10cSrcweir void ForAllRectangles (const Region& rRegion, ::boost::function<void(const Rectangle&)> aFunction)
80cdf0e10cSrcweir {
81cdf0e10cSrcweir     OSL_ASSERT(aFunction);
82e6f63103SArmin Le Grand     RectangleVector aRectangles;
83e6f63103SArmin Le Grand     rRegion.GetRegionRectangles(aRectangles);
84cdf0e10cSrcweir 
85e6f63103SArmin Le Grand     if(0 == aRectangles.size())
86cdf0e10cSrcweir     {
87e6f63103SArmin Le Grand         aFunction(Rectangle());
88cdf0e10cSrcweir     }
89cdf0e10cSrcweir     else
90cdf0e10cSrcweir     {
91e6f63103SArmin Le Grand         for(RectangleVector::const_iterator aRectIter(aRectangles.begin()); aRectIter != aRectangles.end(); aRectIter++)
92e6f63103SArmin Le Grand         {
93e6f63103SArmin Le Grand             aFunction(*aRectIter);
94e6f63103SArmin Le Grand         }
95e6f63103SArmin Le Grand 
96e6f63103SArmin Le Grand         //Region aMutableRegionCopy (rRegion);
97e6f63103SArmin Le Grand         //RegionHandle aHandle(aMutableRegionCopy.BeginEnumRects());
98e6f63103SArmin Le Grand         //Rectangle aBox;
99e6f63103SArmin Le Grand         //while (aMutableRegionCopy.GetEnumRects(aHandle, aBox))
100e6f63103SArmin Le Grand         //  aFunction(aBox);
101e6f63103SArmin Le Grand         //aMutableRegionCopy.EndEnumRects(aHandle);
102cdf0e10cSrcweir     }
103cdf0e10cSrcweir }
104cdf0e10cSrcweir 
105cdf0e10cSrcweir class Layer : private ::boost::noncopyable
106cdf0e10cSrcweir {
107cdf0e10cSrcweir public:
108cdf0e10cSrcweir     Layer (void);
109cdf0e10cSrcweir     ~Layer (void);
110cdf0e10cSrcweir 
111cdf0e10cSrcweir     void Initialize (const SharedSdWindow& rpTargetWindow);
112cdf0e10cSrcweir     void InvalidateRectangle (const Rectangle& rInvalidationBox);
113cdf0e10cSrcweir     void InvalidateRegion (const Region& rInvalidationRegion);
114cdf0e10cSrcweir     void Validate (const MapMode& rMapMode);
115cdf0e10cSrcweir     void Repaint (
116cdf0e10cSrcweir         OutputDevice& rTargetDevice,
117cdf0e10cSrcweir         const Rectangle& rRepaintRectangle);
118cdf0e10cSrcweir     void Resize (const Size& rSize);
119cdf0e10cSrcweir     void AddPainter (const SharedILayerPainter& rpPainter);
120cdf0e10cSrcweir     void RemovePainter (const SharedILayerPainter& rpPainter);
121cdf0e10cSrcweir     bool HasPainter (void) const;
122cdf0e10cSrcweir     void Dispose (void);
123cdf0e10cSrcweir 
124cdf0e10cSrcweir private:
125cdf0e10cSrcweir     ::boost::shared_ptr<VirtualDevice> mpLayerDevice;
126cdf0e10cSrcweir     ::std::vector<SharedILayerPainter> maPainters;
127cdf0e10cSrcweir     Region maInvalidationRegion;
128cdf0e10cSrcweir 
129cdf0e10cSrcweir     void ValidateRectangle (const Rectangle& rBox);
130cdf0e10cSrcweir };
131cdf0e10cSrcweir typedef ::boost::shared_ptr<Layer> SharedLayer;
132cdf0e10cSrcweir 
133cdf0e10cSrcweir 
134cdf0e10cSrcweir } // end of anonymous namespace
135cdf0e10cSrcweir 
136cdf0e10cSrcweir 
137cdf0e10cSrcweir class LayeredDevice::LayerContainer : public ::std::vector<SharedLayer>
138cdf0e10cSrcweir {
139cdf0e10cSrcweir public:
LayerContainer(void)140cdf0e10cSrcweir     LayerContainer (void) {}
~LayerContainer(void)141cdf0e10cSrcweir     ~LayerContainer (void) {}
142cdf0e10cSrcweir };
143cdf0e10cSrcweir 
144cdf0e10cSrcweir 
145cdf0e10cSrcweir 
146cdf0e10cSrcweir 
147cdf0e10cSrcweir //===== LayeredDevice =========================================================
148cdf0e10cSrcweir 
LayeredDevice(const SharedSdWindow & rpTargetWindow)149cdf0e10cSrcweir LayeredDevice::LayeredDevice (const SharedSdWindow& rpTargetWindow)
150cdf0e10cSrcweir     : mpTargetWindow(rpTargetWindow),
151cdf0e10cSrcweir       mpLayers(new LayerContainer()),
152cdf0e10cSrcweir       mpBackBuffer(new VirtualDevice(*mpTargetWindow)),
153cdf0e10cSrcweir       maSavedMapMode(rpTargetWindow->GetMapMode())
154cdf0e10cSrcweir {
155cdf0e10cSrcweir     mpBackBuffer->SetOutputSizePixel(mpTargetWindow->GetSizePixel());
156cdf0e10cSrcweir }
157cdf0e10cSrcweir 
158cdf0e10cSrcweir 
159cdf0e10cSrcweir 
160cdf0e10cSrcweir 
~LayeredDevice(void)161cdf0e10cSrcweir LayeredDevice::~LayeredDevice (void)
162cdf0e10cSrcweir {
163cdf0e10cSrcweir }
164cdf0e10cSrcweir 
165cdf0e10cSrcweir 
166cdf0e10cSrcweir 
167cdf0e10cSrcweir 
Invalidate(const Rectangle & rInvalidationArea,const sal_Int32 nLayer)168cdf0e10cSrcweir void LayeredDevice::Invalidate (
169cdf0e10cSrcweir     const Rectangle& rInvalidationArea,
170cdf0e10cSrcweir     const sal_Int32 nLayer)
171cdf0e10cSrcweir {
172cdf0e10cSrcweir     if (nLayer<0 || size_t(nLayer)>=mpLayers->size())
173cdf0e10cSrcweir     {
174cdf0e10cSrcweir         OSL_ASSERT(nLayer>=0 && size_t(nLayer)<mpLayers->size());
175cdf0e10cSrcweir         return;
176cdf0e10cSrcweir     }
177cdf0e10cSrcweir 
178cdf0e10cSrcweir     (*mpLayers)[nLayer]->InvalidateRectangle(rInvalidationArea);
179cdf0e10cSrcweir }
180cdf0e10cSrcweir 
181cdf0e10cSrcweir 
182cdf0e10cSrcweir 
183cdf0e10cSrcweir 
InvalidateAllLayers(const Rectangle & rInvalidationArea)184cdf0e10cSrcweir void LayeredDevice::InvalidateAllLayers (const Rectangle& rInvalidationArea)
185cdf0e10cSrcweir {
186cdf0e10cSrcweir     for (sal_uInt32 nLayer=0; nLayer<mpLayers->size(); ++nLayer)
187cdf0e10cSrcweir         (*mpLayers)[nLayer]->InvalidateRectangle(rInvalidationArea);
188cdf0e10cSrcweir }
189cdf0e10cSrcweir 
190cdf0e10cSrcweir 
191cdf0e10cSrcweir 
192cdf0e10cSrcweir 
InvalidateAllLayers(const Region & rInvalidationRegion)193cdf0e10cSrcweir void LayeredDevice::InvalidateAllLayers (const Region& rInvalidationRegion)
194cdf0e10cSrcweir {
195cdf0e10cSrcweir     for (sal_uInt32 nLayer=0; nLayer<mpLayers->size(); ++nLayer)
196cdf0e10cSrcweir         (*mpLayers)[nLayer]->InvalidateRegion(rInvalidationRegion);
197cdf0e10cSrcweir }
198cdf0e10cSrcweir 
199cdf0e10cSrcweir 
200cdf0e10cSrcweir 
201cdf0e10cSrcweir 
RegisterPainter(const SharedILayerPainter & rpPainter,const sal_Int32 nLayer)202cdf0e10cSrcweir void LayeredDevice::RegisterPainter (
203cdf0e10cSrcweir     const SharedILayerPainter& rpPainter,
204cdf0e10cSrcweir     const sal_Int32 nLayer)
205cdf0e10cSrcweir {
206cdf0e10cSrcweir     OSL_ASSERT(mpLayers);
207cdf0e10cSrcweir     if ( ! rpPainter)
208cdf0e10cSrcweir     {
209cdf0e10cSrcweir         OSL_ASSERT(rpPainter);
210cdf0e10cSrcweir         return;
211cdf0e10cSrcweir     }
212cdf0e10cSrcweir     if (nLayer<0 || nLayer>=gnMaximumLayerCount)
213cdf0e10cSrcweir     {
214cdf0e10cSrcweir         OSL_ASSERT(nLayer>=0 && nLayer<gnMaximumLayerCount);
215cdf0e10cSrcweir         return;
216cdf0e10cSrcweir     }
217cdf0e10cSrcweir 
218cdf0e10cSrcweir     // Provide the layers.
219cdf0e10cSrcweir     if (sal_uInt32(nLayer) >= mpLayers->size())
220cdf0e10cSrcweir     {
221cdf0e10cSrcweir         const sal_Int32 nOldLayerCount (mpLayers->size());
222cdf0e10cSrcweir         mpLayers->resize(nLayer+1);
223cdf0e10cSrcweir 
224cdf0e10cSrcweir         for (size_t nIndex=nOldLayerCount; nIndex<mpLayers->size(); ++nIndex)
225cdf0e10cSrcweir             (*mpLayers)[nIndex].reset(new Layer());
226cdf0e10cSrcweir     }
227cdf0e10cSrcweir 
228cdf0e10cSrcweir     (*mpLayers)[nLayer]->AddPainter(rpPainter);
229cdf0e10cSrcweir     if (nLayer == 0)
230cdf0e10cSrcweir         (*mpLayers)[nLayer]->Initialize(mpTargetWindow);
231cdf0e10cSrcweir 
232cdf0e10cSrcweir     rpPainter->SetLayerInvalidator(
233cdf0e10cSrcweir         SharedILayerInvalidator(new LayerInvalidator(shared_from_this(),mpTargetWindow,nLayer)));
234cdf0e10cSrcweir }
235cdf0e10cSrcweir 
236cdf0e10cSrcweir 
237cdf0e10cSrcweir 
238cdf0e10cSrcweir 
RemovePainter(const SharedILayerPainter & rpPainter,const sal_Int32 nLayer)239cdf0e10cSrcweir void LayeredDevice::RemovePainter (
240cdf0e10cSrcweir     const SharedILayerPainter& rpPainter,
241cdf0e10cSrcweir     const sal_Int32 nLayer)
242cdf0e10cSrcweir {
243cdf0e10cSrcweir     if ( ! rpPainter)
244cdf0e10cSrcweir     {
245cdf0e10cSrcweir         OSL_ASSERT(rpPainter);
246cdf0e10cSrcweir         return;
247cdf0e10cSrcweir     }
248cdf0e10cSrcweir     if (nLayer<0 || size_t(nLayer)>=mpLayers->size())
249cdf0e10cSrcweir     {
250cdf0e10cSrcweir         OSL_ASSERT(nLayer>=0 && size_t(nLayer)<mpLayers->size());
251cdf0e10cSrcweir         return;
252cdf0e10cSrcweir     }
253cdf0e10cSrcweir 
254cdf0e10cSrcweir     rpPainter->SetLayerInvalidator(SharedILayerInvalidator());
255cdf0e10cSrcweir 
256cdf0e10cSrcweir     (*mpLayers)[nLayer]->RemovePainter(rpPainter);
257cdf0e10cSrcweir 
258cdf0e10cSrcweir     // Remove top most layers that do not contain any painters.
259cdf0e10cSrcweir     while ( ! mpLayers->empty() && ! mpLayers->back()->HasPainter())
260cdf0e10cSrcweir         mpLayers->erase(mpLayers->end()-1);
261cdf0e10cSrcweir }
262cdf0e10cSrcweir 
263cdf0e10cSrcweir 
264cdf0e10cSrcweir 
265cdf0e10cSrcweir 
HasPainter(const sal_Int32 nLayer)266cdf0e10cSrcweir bool LayeredDevice::HasPainter (const sal_Int32 nLayer)
267cdf0e10cSrcweir {
268cdf0e10cSrcweir     return nLayer>=0
269cdf0e10cSrcweir         && sal_uInt32(nLayer)<mpLayers->size()
270cdf0e10cSrcweir         && (*mpLayers)[nLayer]->HasPainter();
271cdf0e10cSrcweir }
272cdf0e10cSrcweir 
273cdf0e10cSrcweir 
274cdf0e10cSrcweir 
275cdf0e10cSrcweir 
Repaint(const Region & rRepaintRegion)276cdf0e10cSrcweir void LayeredDevice::Repaint (const Region& rRepaintRegion)
277cdf0e10cSrcweir {
278cdf0e10cSrcweir     // Validate the contents of all layers (that have their own devices.)
279cdf0e10cSrcweir     ::std::for_each(
280cdf0e10cSrcweir         mpLayers->begin(),
281cdf0e10cSrcweir         mpLayers->end(),
282cdf0e10cSrcweir         ::boost::bind(&Layer::Validate, _1, mpTargetWindow->GetMapMode()));
283cdf0e10cSrcweir 
284cdf0e10cSrcweir     ForAllRectangles(rRepaintRegion, ::boost::bind(&LayeredDevice::RepaintRectangle, this, _1));
285cdf0e10cSrcweir }
286cdf0e10cSrcweir 
287cdf0e10cSrcweir 
288cdf0e10cSrcweir 
289cdf0e10cSrcweir 
RepaintRectangle(const Rectangle & rRepaintRectangle)290cdf0e10cSrcweir void LayeredDevice::RepaintRectangle (const Rectangle& rRepaintRectangle)
291cdf0e10cSrcweir {
292cdf0e10cSrcweir     if (mpLayers->size() == 0)
293cdf0e10cSrcweir         return;
294cdf0e10cSrcweir     else if (mpLayers->size() == 1)
295cdf0e10cSrcweir     {
296cdf0e10cSrcweir         // Just copy the main layer into the target device.
297cdf0e10cSrcweir         (*mpLayers)[0]->Repaint(*mpTargetWindow, rRepaintRectangle);
298cdf0e10cSrcweir     }
299cdf0e10cSrcweir     else
300cdf0e10cSrcweir     {
301cdf0e10cSrcweir         // Paint all layers first into the back buffer (to avoid flickering
302cdf0e10cSrcweir         // due to synchronous paints) and then copy that into the target
303cdf0e10cSrcweir         // device.
304cdf0e10cSrcweir         mpBackBuffer->SetMapMode(mpTargetWindow->GetMapMode());
305cdf0e10cSrcweir         ::std::for_each(
306cdf0e10cSrcweir             mpLayers->begin(),
307cdf0e10cSrcweir             mpLayers->end(),
308cdf0e10cSrcweir             ::boost::bind(&Layer::Repaint, _1, ::boost::ref(*mpBackBuffer), rRepaintRectangle));
309cdf0e10cSrcweir 
310cdf0e10cSrcweir         DeviceCopy(*mpTargetWindow, *mpBackBuffer, rRepaintRectangle);
311cdf0e10cSrcweir     }
312cdf0e10cSrcweir }
313cdf0e10cSrcweir 
314cdf0e10cSrcweir 
315cdf0e10cSrcweir 
316cdf0e10cSrcweir 
Resize(void)317cdf0e10cSrcweir void LayeredDevice::Resize (void)
318cdf0e10cSrcweir {
319cdf0e10cSrcweir     const Size aSize (mpTargetWindow->GetSizePixel());
320cdf0e10cSrcweir     mpBackBuffer->SetOutputSizePixel(aSize);
321cdf0e10cSrcweir     ::std::for_each(mpLayers->begin(), mpLayers->end(), ::boost::bind(&Layer::Resize, _1, aSize));
322cdf0e10cSrcweir }
323cdf0e10cSrcweir 
324cdf0e10cSrcweir 
325cdf0e10cSrcweir 
326cdf0e10cSrcweir 
Dispose(void)327cdf0e10cSrcweir void LayeredDevice::Dispose (void)
328cdf0e10cSrcweir {
329cdf0e10cSrcweir     ::std::for_each(mpLayers->begin(), mpLayers->end(), ::boost::bind(&Layer::Dispose, _1));
330cdf0e10cSrcweir     mpLayers->clear();
331cdf0e10cSrcweir }
332cdf0e10cSrcweir 
333cdf0e10cSrcweir 
334cdf0e10cSrcweir 
335cdf0e10cSrcweir 
HandleMapModeChange(void)336cdf0e10cSrcweir bool LayeredDevice::HandleMapModeChange (void)
337cdf0e10cSrcweir {
338cdf0e10cSrcweir     const MapMode& rMapMode (mpTargetWindow->GetMapMode());
339cdf0e10cSrcweir     if (maSavedMapMode == rMapMode)
340cdf0e10cSrcweir         return false;
341cdf0e10cSrcweir 
342cdf0e10cSrcweir     const Rectangle aLogicWindowBox (
343cdf0e10cSrcweir         mpTargetWindow->PixelToLogic(Rectangle(Point(0,0), mpTargetWindow->GetSizePixel())));
344cdf0e10cSrcweir     if (maSavedMapMode.GetScaleX() != rMapMode.GetScaleX()
345cdf0e10cSrcweir         || maSavedMapMode.GetScaleY() != rMapMode.GetScaleY()
346cdf0e10cSrcweir         || maSavedMapMode.GetMapUnit() != rMapMode.GetMapUnit())
347cdf0e10cSrcweir     {
348cdf0e10cSrcweir         // When the scale has changed then we have to paint everything.
349cdf0e10cSrcweir         InvalidateAllLayers(aLogicWindowBox);
350cdf0e10cSrcweir     }
351cdf0e10cSrcweir     else if (maSavedMapMode.GetOrigin() != rMapMode.GetOrigin())
352cdf0e10cSrcweir     {
353cdf0e10cSrcweir         // Window has been scrolled. Adapt contents of backbuffers and
354cdf0e10cSrcweir         // layer devices.
355cdf0e10cSrcweir         const Point aDelta (rMapMode.GetOrigin() - maSavedMapMode.GetOrigin());
356cdf0e10cSrcweir         mpBackBuffer->CopyArea(
357cdf0e10cSrcweir             aLogicWindowBox.TopLeft(),
358cdf0e10cSrcweir             mpTargetWindow->PixelToLogic(Point(0,0), maSavedMapMode),
359cdf0e10cSrcweir             aLogicWindowBox.GetSize());
360cdf0e10cSrcweir 
361cdf0e10cSrcweir         // Invalidate the area(s) that have been exposed.
362cdf0e10cSrcweir         const Rectangle aWindowBox (Point(0,0), mpTargetWindow->GetSizePixel());
363cdf0e10cSrcweir         if (aDelta.Y() < 0)
364cdf0e10cSrcweir             InvalidateAllLayers(mpTargetWindow->PixelToLogic(Rectangle(
365cdf0e10cSrcweir                 aWindowBox.Left(),
366cdf0e10cSrcweir                 aWindowBox.Bottom()+aDelta.Y(),
367cdf0e10cSrcweir                 aWindowBox.Right(),
368cdf0e10cSrcweir                 aWindowBox.Bottom())));
369cdf0e10cSrcweir         else if (aDelta.Y() > 0)
370cdf0e10cSrcweir             InvalidateAllLayers(mpTargetWindow->PixelToLogic(Rectangle(
371cdf0e10cSrcweir                 aWindowBox.Left(),
372cdf0e10cSrcweir                 aWindowBox.Top(),
373cdf0e10cSrcweir                 aWindowBox.Right(),
374cdf0e10cSrcweir                 aWindowBox.Top()+aDelta.Y())));
375cdf0e10cSrcweir         if (aDelta.X() < 0)
376cdf0e10cSrcweir             InvalidateAllLayers(mpTargetWindow->PixelToLogic(Rectangle(
377cdf0e10cSrcweir                 aWindowBox.Right()+aDelta.X(),
378cdf0e10cSrcweir                 aWindowBox.Top(),
379cdf0e10cSrcweir                 aWindowBox.Right(),
380cdf0e10cSrcweir                 aWindowBox.Bottom())));
381cdf0e10cSrcweir         else if (aDelta.X() > 0)
382cdf0e10cSrcweir             InvalidateAllLayers(mpTargetWindow->PixelToLogic(Rectangle(
383cdf0e10cSrcweir                 aWindowBox.Left(),
384cdf0e10cSrcweir                 aWindowBox.Top(),
385cdf0e10cSrcweir                 aWindowBox.Left()+aDelta.X(),
386cdf0e10cSrcweir                 aWindowBox.Bottom())));
387cdf0e10cSrcweir     }
388cdf0e10cSrcweir     else
389cdf0e10cSrcweir     {
390*9816bc04Smseidel         // Can this happen? Let's trigger a warning when it does.
391cdf0e10cSrcweir         OSL_ASSERT(false);
392cdf0e10cSrcweir     }
393cdf0e10cSrcweir 
394cdf0e10cSrcweir     maSavedMapMode = rMapMode;
395cdf0e10cSrcweir 
396cdf0e10cSrcweir     return true;
397cdf0e10cSrcweir }
398cdf0e10cSrcweir 
399cdf0e10cSrcweir 
400cdf0e10cSrcweir 
401cdf0e10cSrcweir 
402cdf0e10cSrcweir //===== Layer =================================================================
403cdf0e10cSrcweir 
Layer(void)404cdf0e10cSrcweir Layer::Layer (void)
405cdf0e10cSrcweir     : mpLayerDevice(),
406cdf0e10cSrcweir       maPainters(),
407cdf0e10cSrcweir       maInvalidationRegion()
408cdf0e10cSrcweir {
409cdf0e10cSrcweir }
410cdf0e10cSrcweir 
411cdf0e10cSrcweir 
412cdf0e10cSrcweir 
413cdf0e10cSrcweir 
~Layer(void)414cdf0e10cSrcweir Layer::~Layer (void)
415cdf0e10cSrcweir {
416cdf0e10cSrcweir }
417cdf0e10cSrcweir 
418cdf0e10cSrcweir 
419cdf0e10cSrcweir 
420cdf0e10cSrcweir 
Initialize(const SharedSdWindow & rpTargetWindow)421cdf0e10cSrcweir void Layer::Initialize (const SharedSdWindow& rpTargetWindow)
422cdf0e10cSrcweir {
423cdf0e10cSrcweir #if 0
424cdf0e10cSrcweir     (void)rpTargetWindow;
425cdf0e10cSrcweir #else
426cdf0e10cSrcweir     if ( ! mpLayerDevice)
427cdf0e10cSrcweir     {
428cdf0e10cSrcweir         mpLayerDevice.reset(new VirtualDevice(*rpTargetWindow));
429cdf0e10cSrcweir         mpLayerDevice->SetOutputSizePixel(rpTargetWindow->GetSizePixel());
430cdf0e10cSrcweir     }
431cdf0e10cSrcweir #endif
432cdf0e10cSrcweir }
433cdf0e10cSrcweir 
434cdf0e10cSrcweir 
435cdf0e10cSrcweir 
436cdf0e10cSrcweir 
InvalidateRectangle(const Rectangle & rInvalidationBox)437cdf0e10cSrcweir void Layer::InvalidateRectangle (const Rectangle& rInvalidationBox)
438cdf0e10cSrcweir {
439cdf0e10cSrcweir     maInvalidationRegion.Union(rInvalidationBox);
440cdf0e10cSrcweir }
441cdf0e10cSrcweir 
442cdf0e10cSrcweir 
443cdf0e10cSrcweir 
444cdf0e10cSrcweir 
InvalidateRegion(const Region & rInvalidationRegion)445cdf0e10cSrcweir void Layer::InvalidateRegion (const Region& rInvalidationRegion)
446cdf0e10cSrcweir {
447cdf0e10cSrcweir     maInvalidationRegion.Union(rInvalidationRegion);
448cdf0e10cSrcweir }
449cdf0e10cSrcweir 
450cdf0e10cSrcweir 
451cdf0e10cSrcweir 
452cdf0e10cSrcweir 
Validate(const MapMode & rMapMode)453cdf0e10cSrcweir void Layer::Validate (const MapMode& rMapMode)
454cdf0e10cSrcweir {
455cdf0e10cSrcweir     if (mpLayerDevice && ! maInvalidationRegion.IsEmpty())
456cdf0e10cSrcweir     {
457cdf0e10cSrcweir         Region aRegion (maInvalidationRegion);
458cdf0e10cSrcweir         maInvalidationRegion.SetEmpty();
459cdf0e10cSrcweir 
460cdf0e10cSrcweir         mpLayerDevice->SetMapMode(rMapMode);
461cdf0e10cSrcweir         ForAllRectangles(
462cdf0e10cSrcweir             aRegion,
463cdf0e10cSrcweir             ::boost::bind(&Layer::ValidateRectangle, this, _1));
464cdf0e10cSrcweir     }
465cdf0e10cSrcweir }
466cdf0e10cSrcweir 
467cdf0e10cSrcweir 
468cdf0e10cSrcweir 
469cdf0e10cSrcweir 
ValidateRectangle(const Rectangle & rBox)470cdf0e10cSrcweir void Layer::ValidateRectangle (const Rectangle& rBox)
471cdf0e10cSrcweir {
472cdf0e10cSrcweir     if ( ! mpLayerDevice)
473cdf0e10cSrcweir         return;
474cdf0e10cSrcweir     const Region aSavedClipRegion (mpLayerDevice->GetClipRegion());
475cdf0e10cSrcweir     mpLayerDevice->IntersectClipRegion(rBox);
476cdf0e10cSrcweir 
477cdf0e10cSrcweir     for (::std::vector<SharedILayerPainter>::const_iterator
478cdf0e10cSrcweir               iPainter(maPainters.begin()),
479cdf0e10cSrcweir               iEnd(maPainters.end());
480cdf0e10cSrcweir          iPainter!=iEnd;
481cdf0e10cSrcweir          ++iPainter)
482cdf0e10cSrcweir     {
483cdf0e10cSrcweir         (*iPainter)->Paint(*mpLayerDevice, rBox);
484cdf0e10cSrcweir     }
485cdf0e10cSrcweir 
486cdf0e10cSrcweir     mpLayerDevice->SetClipRegion(aSavedClipRegion);
487cdf0e10cSrcweir }
488cdf0e10cSrcweir 
489cdf0e10cSrcweir 
490cdf0e10cSrcweir 
491cdf0e10cSrcweir 
Repaint(OutputDevice & rTargetDevice,const Rectangle & rRepaintRectangle)492cdf0e10cSrcweir void Layer::Repaint (
493cdf0e10cSrcweir     OutputDevice& rTargetDevice,
494cdf0e10cSrcweir     const Rectangle& rRepaintRectangle)
495cdf0e10cSrcweir {
496cdf0e10cSrcweir     if (mpLayerDevice)
497cdf0e10cSrcweir     {
498cdf0e10cSrcweir         DeviceCopy(rTargetDevice, *mpLayerDevice, rRepaintRectangle);
499cdf0e10cSrcweir     }
500cdf0e10cSrcweir     else
501cdf0e10cSrcweir     {
502cdf0e10cSrcweir         ::std::for_each(
503cdf0e10cSrcweir             maPainters.begin(),
504cdf0e10cSrcweir             maPainters.end(),
505cdf0e10cSrcweir             ::boost::bind(&ILayerPainter::Paint,
506cdf0e10cSrcweir                 _1,
507cdf0e10cSrcweir                 ::boost::ref(rTargetDevice),
508cdf0e10cSrcweir                 rRepaintRectangle));
509cdf0e10cSrcweir     }
510cdf0e10cSrcweir }
511cdf0e10cSrcweir 
512cdf0e10cSrcweir 
513cdf0e10cSrcweir 
514cdf0e10cSrcweir 
Resize(const Size & rSize)515cdf0e10cSrcweir void Layer::Resize (const Size& rSize)
516cdf0e10cSrcweir {
517cdf0e10cSrcweir     if (mpLayerDevice)
518cdf0e10cSrcweir     {
519cdf0e10cSrcweir         mpLayerDevice->SetOutputSizePixel(rSize);
520cdf0e10cSrcweir         maInvalidationRegion = Rectangle(Point(0,0), rSize);
521cdf0e10cSrcweir     }
522cdf0e10cSrcweir }
523cdf0e10cSrcweir 
524cdf0e10cSrcweir 
525cdf0e10cSrcweir 
526cdf0e10cSrcweir 
AddPainter(const SharedILayerPainter & rpPainter)527cdf0e10cSrcweir void Layer::AddPainter (const SharedILayerPainter& rpPainter)
528cdf0e10cSrcweir {
529cdf0e10cSrcweir     OSL_ASSERT(::std::find(maPainters.begin(), maPainters.end(), rpPainter) == maPainters.end());
530cdf0e10cSrcweir 
531cdf0e10cSrcweir     maPainters.push_back(rpPainter);
532cdf0e10cSrcweir }
533cdf0e10cSrcweir 
534cdf0e10cSrcweir 
535cdf0e10cSrcweir 
536cdf0e10cSrcweir 
RemovePainter(const SharedILayerPainter & rpPainter)537cdf0e10cSrcweir void Layer::RemovePainter (const SharedILayerPainter& rpPainter)
538cdf0e10cSrcweir {
539cdf0e10cSrcweir     const ::std::vector<SharedILayerPainter>::iterator iPainter (
540cdf0e10cSrcweir         ::std::find(maPainters.begin(), maPainters.end(), rpPainter));
541cdf0e10cSrcweir     if (iPainter != maPainters.end())
542cdf0e10cSrcweir     {
543cdf0e10cSrcweir         maPainters.erase(iPainter);
544cdf0e10cSrcweir     }
545cdf0e10cSrcweir     else
546cdf0e10cSrcweir     {
547cdf0e10cSrcweir         DBG_ASSERT(false,"LayeredDevice::RemovePainter called for painter that is not registered");
548cdf0e10cSrcweir     }
549cdf0e10cSrcweir }
550cdf0e10cSrcweir 
551cdf0e10cSrcweir 
552cdf0e10cSrcweir 
553cdf0e10cSrcweir 
HasPainter(void) const554cdf0e10cSrcweir bool Layer::HasPainter (void) const
555cdf0e10cSrcweir {
556cdf0e10cSrcweir     return !maPainters.empty();
557cdf0e10cSrcweir }
558cdf0e10cSrcweir 
559cdf0e10cSrcweir 
560cdf0e10cSrcweir 
561cdf0e10cSrcweir 
Dispose(void)562cdf0e10cSrcweir void Layer::Dispose (void)
563cdf0e10cSrcweir {
564cdf0e10cSrcweir     maPainters.clear();
565cdf0e10cSrcweir }
566cdf0e10cSrcweir 
567cdf0e10cSrcweir 
568cdf0e10cSrcweir } } } // end of namespace ::sd::slidesorter::view
569