xref: /trunk/main/svx/source/sdr/overlay/overlaymanagerbuffered.cxx (revision 07ec2dae6a42189124ed7f901d54c35a0555ec96)
1f6e50924SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3f6e50924SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4f6e50924SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5f6e50924SAndrew Rist  * distributed with this work for additional information
6f6e50924SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7f6e50924SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8f6e50924SAndrew Rist  * "License"); you may not use this file except in compliance
9f6e50924SAndrew Rist  * with the License.  You may obtain a copy of the License at
10cdf0e10cSrcweir  *
11f6e50924SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir  *
13f6e50924SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14f6e50924SAndrew Rist  * software distributed under the License is distributed on an
15f6e50924SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16f6e50924SAndrew Rist  * KIND, either express or implied.  See the License for the
17f6e50924SAndrew Rist  * specific language governing permissions and limitations
18f6e50924SAndrew Rist  * under the License.
19cdf0e10cSrcweir  *
20f6e50924SAndrew Rist  *************************************************************/
21f6e50924SAndrew Rist 
22cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
23cdf0e10cSrcweir #include "precompiled_svx.hxx"
24cdf0e10cSrcweir #include <svx/sdr/overlay/overlaymanagerbuffered.hxx>
25cdf0e10cSrcweir #include <vcl/outdev.hxx>
26cdf0e10cSrcweir #include <basegfx/point/b2dpoint.hxx>
27cdf0e10cSrcweir #include <basegfx/range/b2drange.hxx>
28cdf0e10cSrcweir #include <vcl/salbtype.hxx>
29cdf0e10cSrcweir #include <vcl/window.hxx>
30cdf0e10cSrcweir #include <vcl/bitmap.hxx>
31cdf0e10cSrcweir #include <tools/stream.hxx>
32cdf0e10cSrcweir #include <basegfx/matrix/b2dhommatrix.hxx>
33cdf0e10cSrcweir #include <vcl/cursor.hxx>
3445fd3b9aSArmin Le Grand #include <vcl/dibtools.hxx>
35cdf0e10cSrcweir 
36cdf0e10cSrcweir namespace sdr
37cdf0e10cSrcweir {
38cdf0e10cSrcweir     namespace overlay
39cdf0e10cSrcweir     {
ImpPrepareBufferDevice()40cdf0e10cSrcweir         void OverlayManagerBuffered::ImpPrepareBufferDevice()
41cdf0e10cSrcweir         {
42cdf0e10cSrcweir             // compare size of maBufferDevice with size of visible area
43cdf0e10cSrcweir             if(maBufferDevice.GetOutputSizePixel() != getOutputDevice().GetOutputSizePixel())
44cdf0e10cSrcweir             {
45cdf0e10cSrcweir                 // set new buffer size, copy as much content as possible (use bool parameter for vcl).
46cdf0e10cSrcweir                 // Newly uncovered regions will be repainted.
47cdf0e10cSrcweir                 maBufferDevice.SetOutputSizePixel(getOutputDevice().GetOutputSizePixel(), false);
48cdf0e10cSrcweir             }
49cdf0e10cSrcweir 
50cdf0e10cSrcweir             // compare the MapModes for zoom/scroll changes
51cdf0e10cSrcweir             if(maBufferDevice.GetMapMode() != getOutputDevice().GetMapMode())
52cdf0e10cSrcweir             {
53cdf0e10cSrcweir                 const bool bZoomed(
54cdf0e10cSrcweir                     maBufferDevice.GetMapMode().GetScaleX() != getOutputDevice().GetMapMode().GetScaleX()
55cdf0e10cSrcweir                     || maBufferDevice.GetMapMode().GetScaleY() != getOutputDevice().GetMapMode().GetScaleY());
56cdf0e10cSrcweir 
57cdf0e10cSrcweir                 if(!bZoomed)
58cdf0e10cSrcweir                 {
59cdf0e10cSrcweir                     const Point& rOriginOld = maBufferDevice.GetMapMode().GetOrigin();
60cdf0e10cSrcweir                     const Point& rOriginNew = getOutputDevice().GetMapMode().GetOrigin();
61cdf0e10cSrcweir                     const bool bScrolled(rOriginOld != rOriginNew);
62cdf0e10cSrcweir 
63cdf0e10cSrcweir                     if(bScrolled)
64cdf0e10cSrcweir                     {
65cdf0e10cSrcweir                         // get pixel bounds
66cdf0e10cSrcweir                         const Point aOriginOldPixel(maBufferDevice.LogicToPixel(rOriginOld));
67cdf0e10cSrcweir                         const Point aOriginNewPixel(maBufferDevice.LogicToPixel(rOriginNew));
68cdf0e10cSrcweir                         const Size aOutputSizePixel(maBufferDevice.GetOutputSizePixel());
69cdf0e10cSrcweir 
70cdf0e10cSrcweir                         // remember and switch off MapMode
71cdf0e10cSrcweir                         const bool bMapModeWasEnabled(maBufferDevice.IsMapModeEnabled());
72cdf0e10cSrcweir                         maBufferDevice.EnableMapMode(false);
73cdf0e10cSrcweir 
74cdf0e10cSrcweir                         // scroll internally buffered stuff
75cdf0e10cSrcweir                         const Point aDestinationOffsetPixel(aOriginNewPixel - aOriginOldPixel);
76cdf0e10cSrcweir                         maBufferDevice.DrawOutDev(
77cdf0e10cSrcweir                             aDestinationOffsetPixel, aOutputSizePixel, // destination
78cdf0e10cSrcweir                             Point(), aOutputSizePixel); // source
79cdf0e10cSrcweir 
80cdf0e10cSrcweir                         // restore MapMode
81cdf0e10cSrcweir                         maBufferDevice.EnableMapMode(bMapModeWasEnabled);
82cdf0e10cSrcweir 
83cdf0e10cSrcweir                         // scroll remembered region, too.
84cdf0e10cSrcweir                         if(!maBufferRememberedRangePixel.isEmpty())
85cdf0e10cSrcweir                         {
86cdf0e10cSrcweir                             const basegfx::B2IPoint aIPointDestinationOffsetPixel(aDestinationOffsetPixel.X(), aDestinationOffsetPixel.Y());
87cdf0e10cSrcweir                             const basegfx::B2IPoint aNewMinimum(maBufferRememberedRangePixel.getMinimum() + aIPointDestinationOffsetPixel);
88cdf0e10cSrcweir                             const basegfx::B2IPoint aNewMaximum(maBufferRememberedRangePixel.getMaximum() + aIPointDestinationOffsetPixel);
89cdf0e10cSrcweir                             maBufferRememberedRangePixel = basegfx::B2IRange(aNewMinimum, aNewMaximum);
90cdf0e10cSrcweir                         }
91cdf0e10cSrcweir                     }
92cdf0e10cSrcweir                 }
93cdf0e10cSrcweir 
94cdf0e10cSrcweir                 // copy new MapMode
95cdf0e10cSrcweir                 maBufferDevice.SetMapMode(getOutputDevice().GetMapMode());
96cdf0e10cSrcweir             }
97cdf0e10cSrcweir 
98cdf0e10cSrcweir             // #i29186#
99cdf0e10cSrcweir             maBufferDevice.SetDrawMode(getOutputDevice().GetDrawMode());
100cdf0e10cSrcweir             maBufferDevice.SetSettings(getOutputDevice().GetSettings());
101cdf0e10cSrcweir             maBufferDevice.SetAntialiasing(getOutputDevice().GetAntialiasing());
102cdf0e10cSrcweir         }
103cdf0e10cSrcweir 
ImpRestoreBackground() const104cdf0e10cSrcweir         void OverlayManagerBuffered::ImpRestoreBackground() const
105cdf0e10cSrcweir         {
106cdf0e10cSrcweir             const Rectangle aRegionRectanglePixel(
107cdf0e10cSrcweir                 maBufferRememberedRangePixel.getMinX(), maBufferRememberedRangePixel.getMinY(),
108cdf0e10cSrcweir                 maBufferRememberedRangePixel.getMaxX(), maBufferRememberedRangePixel.getMaxY());
109cdf0e10cSrcweir             const Region aRegionPixel(aRegionRectanglePixel);
110cdf0e10cSrcweir 
111cdf0e10cSrcweir             ImpRestoreBackground(aRegionPixel);
112cdf0e10cSrcweir         }
113cdf0e10cSrcweir 
ImpRestoreBackground(const Region & rRegionPixel) const114cdf0e10cSrcweir         void OverlayManagerBuffered::ImpRestoreBackground(const Region& rRegionPixel) const
115cdf0e10cSrcweir         {
116cdf0e10cSrcweir             // MapModes off
117cdf0e10cSrcweir             const bool bMapModeWasEnabledDest(getOutputDevice().IsMapModeEnabled());
118cdf0e10cSrcweir             const bool bMapModeWasEnabledSource(maBufferDevice.IsMapModeEnabled());
119cdf0e10cSrcweir             getOutputDevice().EnableMapMode(false);
120cdf0e10cSrcweir             ((OverlayManagerBuffered*)this)->maBufferDevice.EnableMapMode(false);
121cdf0e10cSrcweir 
122e6f63103SArmin Le Grand             // local region
123e6f63103SArmin Le Grand             RectangleVector aRectangles;
124e6f63103SArmin Le Grand             rRegionPixel.GetRegionRectangles(aRectangles);
125e6f63103SArmin Le Grand 
126e6f63103SArmin Le Grand             for(RectangleVector::const_iterator aRectIter(aRectangles.begin()); aRectIter != aRectangles.end(); aRectIter++)
127cdf0e10cSrcweir             {
128cdf0e10cSrcweir #ifdef DBG_UTIL
129cdf0e10cSrcweir                 // #i72754# possible graphical region test only with non-pro
130cdf0e10cSrcweir                 static bool bDoPaintForVisualControl(false);
131e6f63103SArmin Le Grand 
132cdf0e10cSrcweir                 if(bDoPaintForVisualControl)
133cdf0e10cSrcweir                 {
134cdf0e10cSrcweir                     getOutputDevice().SetLineColor(COL_LIGHTGREEN);
135cdf0e10cSrcweir                     getOutputDevice().SetFillColor();
136e6f63103SArmin Le Grand                     getOutputDevice().DrawRect(*aRectIter);
137cdf0e10cSrcweir                 }
138cdf0e10cSrcweir #endif
139cdf0e10cSrcweir 
140cdf0e10cSrcweir                 // restore the area
141e6f63103SArmin Le Grand                 const Point aTopLeft(aRectIter->TopLeft());
142e6f63103SArmin Le Grand                 const Size aSize(aRectIter->GetSize());
143cdf0e10cSrcweir 
144cdf0e10cSrcweir                 getOutputDevice().DrawOutDev(
145cdf0e10cSrcweir                     aTopLeft, aSize, // destination
146cdf0e10cSrcweir                     aTopLeft, aSize, // source
147cdf0e10cSrcweir                     maBufferDevice);
148cdf0e10cSrcweir             }
149cdf0e10cSrcweir 
150e6f63103SArmin Le Grand             //Region aRegionPixel(rRegionPixel);
151e6f63103SArmin Le Grand             //RegionHandle aRegionHandle(aRegionPixel.BeginEnumRects());
152e6f63103SArmin Le Grand             //Rectangle aRegionRectanglePixel;
153e6f63103SArmin Le Grand             //
154e6f63103SArmin Le Grand             //while(aRegionPixel.GetEnumRects(aRegionHandle, aRegionRectanglePixel))
155e6f63103SArmin Le Grand             //{
156e6f63103SArmin Le Grand #ifdef DBG_U//TIL
157e6f63103SArmin Le Grand             //  // #i72754# possible graphical region test only with non-pro
158e6f63103SArmin Le Grand             //  static bool bDoPaintForVisualControl(false);
159e6f63103SArmin Le Grand             //  if(bDoPaintForVisualControl)
160e6f63103SArmin Le Grand             //  {
161e6f63103SArmin Le Grand             //      getOutputDevice().SetLineColor(COL_LIGHTGREEN);
162e6f63103SArmin Le Grand             //      getOutputDevice().SetFillColor();
163e6f63103SArmin Le Grand             //      getOutputDevice().DrawRect(aRegionRectanglePixel);
164e6f63103SArmin Le Grand             //  }
165e6f63103SArmin Le Grand #endif      //
166e6f63103SArmin Le Grand             //  // restore the area
167e6f63103SArmin Le Grand             //  const Point aTopLeft(aRegionRectanglePixel.TopLeft());
168e6f63103SArmin Le Grand             //  const Size aSize(aRegionRectanglePixel.GetSize());
169e6f63103SArmin Le Grand             //
170e6f63103SArmin Le Grand             //  getOutputDevice().DrawOutDev(
171e6f63103SArmin Le Grand             //      aTopLeft, aSize, // destination
172e6f63103SArmin Le Grand             //      aTopLeft, aSize, // source
173e6f63103SArmin Le Grand             //      maBufferDevice);
174e6f63103SArmin Le Grand             //}
175e6f63103SArmin Le Grand             //
176e6f63103SArmin Le Grand             //aRegionPixel.EndEnumRects(aRegionHandle);
177cdf0e10cSrcweir 
178cdf0e10cSrcweir             // restore MapModes
179cdf0e10cSrcweir             getOutputDevice().EnableMapMode(bMapModeWasEnabledDest);
180cdf0e10cSrcweir             ((OverlayManagerBuffered*)this)->maBufferDevice.EnableMapMode(bMapModeWasEnabledSource);
181cdf0e10cSrcweir         }
182cdf0e10cSrcweir 
ImpSaveBackground(const Region & rRegion,OutputDevice * pPreRenderDevice)183cdf0e10cSrcweir         void OverlayManagerBuffered::ImpSaveBackground(const Region& rRegion, OutputDevice* pPreRenderDevice)
184cdf0e10cSrcweir         {
185cdf0e10cSrcweir             // prepare source
186cdf0e10cSrcweir             OutputDevice& rSource = (pPreRenderDevice) ? *pPreRenderDevice : getOutputDevice();
187cdf0e10cSrcweir 
188cdf0e10cSrcweir             // Ensure buffer is valid
189cdf0e10cSrcweir             ImpPrepareBufferDevice();
190cdf0e10cSrcweir 
191cdf0e10cSrcweir             // build region which needs to be copied
192cdf0e10cSrcweir             Region aRegion(rSource.LogicToPixel(rRegion));
193cdf0e10cSrcweir 
194cdf0e10cSrcweir             // limit to PaintRegion if it's a window. This will be evtl. the expanded one,
195cdf0e10cSrcweir             // but always the exact redraw area
196cdf0e10cSrcweir             if(OUTDEV_WINDOW == rSource.GetOutDevType())
197cdf0e10cSrcweir             {
198cdf0e10cSrcweir                 Window& rWindow = (Window&)rSource;
199cdf0e10cSrcweir                 Region aPaintRegionPixel = rWindow.LogicToPixel(rWindow.GetPaintRegion());
200cdf0e10cSrcweir                 aRegion.Intersect(aPaintRegionPixel);
201cdf0e10cSrcweir 
202*07ec2daeSmseidel                 // #i72754# Make sure content is completely rendered, the window
203cdf0e10cSrcweir                 // will be used as source of a DrawOutDev soon
204cdf0e10cSrcweir                 rWindow.Flush();
205cdf0e10cSrcweir             }
206cdf0e10cSrcweir 
207cdf0e10cSrcweir             // also limit to buffer size
208e6f63103SArmin Le Grand             const Rectangle aBufferDeviceRectanglePixel(Point(), maBufferDevice.GetOutputSizePixel());
209cdf0e10cSrcweir             aRegion.Intersect(aBufferDeviceRectanglePixel);
210cdf0e10cSrcweir 
211cdf0e10cSrcweir             // MapModes off
212cdf0e10cSrcweir             const bool bMapModeWasEnabledDest(rSource.IsMapModeEnabled());
213cdf0e10cSrcweir             const bool bMapModeWasEnabledSource(maBufferDevice.IsMapModeEnabled());
214cdf0e10cSrcweir             rSource.EnableMapMode(false);
215cdf0e10cSrcweir             maBufferDevice.EnableMapMode(false);
216cdf0e10cSrcweir 
217e6f63103SArmin Le Grand             // prepare to iterate over the rectangles from the region in pixels
218e6f63103SArmin Le Grand             RectangleVector aRectangles;
219e6f63103SArmin Le Grand             aRegion.GetRegionRectangles(aRectangles);
220e6f63103SArmin Le Grand 
221e6f63103SArmin Le Grand             for(RectangleVector::const_iterator aRectIter(aRectangles.begin()); aRectIter != aRectangles.end(); aRectIter++)
222cdf0e10cSrcweir             {
223cdf0e10cSrcweir                 // for each rectangle, save the area
224e6f63103SArmin Le Grand                 const Point aTopLeft(aRectIter->TopLeft());
225e6f63103SArmin Le Grand                 const Size aSize(aRectIter->GetSize());
226cdf0e10cSrcweir 
227cdf0e10cSrcweir                 maBufferDevice.DrawOutDev(
228cdf0e10cSrcweir                     aTopLeft, aSize, // destination
229cdf0e10cSrcweir                     aTopLeft, aSize, // source
230cdf0e10cSrcweir                     rSource);
231cdf0e10cSrcweir 
232cdf0e10cSrcweir #ifdef DBG_UTIL
233cdf0e10cSrcweir                 // #i72754# possible graphical region test only with non-pro
234cdf0e10cSrcweir                 static bool bDoPaintForVisualControl(false);
235e6f63103SArmin Le Grand 
236cdf0e10cSrcweir                 if(bDoPaintForVisualControl)
237cdf0e10cSrcweir                 {
238cdf0e10cSrcweir                     const bool bMapModeWasEnabledTest(getOutputDevice().IsMapModeEnabled());
239e6f63103SArmin Le Grand 
240cdf0e10cSrcweir                     getOutputDevice().EnableMapMode(false);
241cdf0e10cSrcweir                     getOutputDevice().SetLineColor(COL_LIGHTRED);
242cdf0e10cSrcweir                     getOutputDevice().SetFillColor();
243e6f63103SArmin Le Grand                     getOutputDevice().DrawRect(*aRectIter);
244cdf0e10cSrcweir                     getOutputDevice().EnableMapMode(bMapModeWasEnabledTest);
245cdf0e10cSrcweir                 }
246cdf0e10cSrcweir 
247cdf0e10cSrcweir                 static bool bDoSaveForVisualControl(false);
248e6f63103SArmin Le Grand 
249cdf0e10cSrcweir                 if(bDoSaveForVisualControl)
250cdf0e10cSrcweir                 {
251cdf0e10cSrcweir                     const Bitmap aBitmap(maBufferDevice.GetBitmap(aTopLeft, aSize));
252cdf0e10cSrcweir                     SvFileStream aNew((const String&)String(ByteString( "c:\\test.bmp" ), RTL_TEXTENCODING_UTF8), STREAM_WRITE|STREAM_TRUNC);
25345fd3b9aSArmin Le Grand                     WriteDIB(aBitmap, aNew, false, true);
254cdf0e10cSrcweir                 }
255cdf0e10cSrcweir #endif
256cdf0e10cSrcweir             }
257cdf0e10cSrcweir 
258e6f63103SArmin Le Grand             //RegionHandle aRegionHandle(aRegion.BeginEnumRects());
259e6f63103SArmin Le Grand             //Rectangle aRegionRectanglePixel;
260e6f63103SArmin Le Grand             //
261e6f63103SArmin Le Grand             //while(aRegion.GetEnumRects(aRegionHandle, aRegionRectanglePixel))
262e6f63103SArmin Le Grand             //{
263e6f63103SArmin Le Grand             //  // for each rectangle, save the area
264e6f63103SArmin Le Grand             //  Point aTopLeft(aRegionRectanglePixel.TopLeft());
265e6f63103SArmin Le Grand             //  Size aSize(aRegionRectanglePixel.GetSize());
266e6f63103SArmin Le Grand             //
267e6f63103SArmin Le Grand             //  maBufferDevice.DrawOutDev(
268e6f63103SArmin Le Grand             //      aTopLeft, aSize, // destination
269e6f63103SArmin Le Grand             //      aTopLeft, aSize, // source
270e6f63103SArmin Le Grand             //      rSource);
271e6f63103SArmin Le Grand             //
272e6f63103SArmin Le Grand #ifdef DBG_U//TIL
273e6f63103SArmin Le Grand             //  // #i72754# possible graphical region test only with non-pro
274e6f63103SArmin Le Grand             //  static bool bDoPaintForVisualControl(false);
275e6f63103SArmin Le Grand             //  if(bDoPaintForVisualControl)
276e6f63103SArmin Le Grand             //  {
277e6f63103SArmin Le Grand             //      const bool bMapModeWasEnabledTest(getOutputDevice().IsMapModeEnabled());
278e6f63103SArmin Le Grand             //      getOutputDevice().EnableMapMode(false);
279e6f63103SArmin Le Grand             //      getOutputDevice().SetLineColor(COL_LIGHTRED);
280e6f63103SArmin Le Grand             //      getOutputDevice().SetFillColor();
281e6f63103SArmin Le Grand             //      getOutputDevice().DrawRect(aRegionRectanglePixel);
282e6f63103SArmin Le Grand             //      getOutputDevice().EnableMapMode(bMapModeWasEnabledTest);
283e6f63103SArmin Le Grand             //  }
284e6f63103SArmin Le Grand             //
285e6f63103SArmin Le Grand             //  static bool bDoSaveForVisualControl(false);
286e6f63103SArmin Le Grand             //  if(bDoSaveForVisualControl)
287e6f63103SArmin Le Grand             //  {
288e6f63103SArmin Le Grand             //      const Bitmap aBitmap(maBufferDevice.GetBitmap(aTopLeft, aSize));
289e6f63103SArmin Le Grand             //      SvFileStream aNew((const String&)String(ByteString( "c:\\test.bmp" ), RTL_TEXTENCODING_UTF8), STREAM_WRITE|STREAM_TRUNC);
290e6f63103SArmin Le Grand             //      aNew << aBitmap;
291e6f63103SArmin Le Grand             //  }
292e6f63103SArmin Le Grand #endif      //
293e6f63103SArmin Le Grand             //}
294e6f63103SArmin Le Grand             //
295e6f63103SArmin Le Grand             //aRegion.EndEnumRects(aRegionHandle);
296cdf0e10cSrcweir 
297cdf0e10cSrcweir             // restore MapModes
298cdf0e10cSrcweir             rSource.EnableMapMode(bMapModeWasEnabledDest);
299cdf0e10cSrcweir             maBufferDevice.EnableMapMode(bMapModeWasEnabledSource);
300cdf0e10cSrcweir         }
301cdf0e10cSrcweir 
302cdf0e10cSrcweir         IMPL_LINK(OverlayManagerBuffered, ImpBufferTimerHandler, AutoTimer*, /*pTimer*/)
303cdf0e10cSrcweir         {
304cdf0e10cSrcweir             // stop timer
305cdf0e10cSrcweir             maBufferTimer.Stop();
306cdf0e10cSrcweir 
307cdf0e10cSrcweir             if(!maBufferRememberedRangePixel.isEmpty())
308cdf0e10cSrcweir             {
309cdf0e10cSrcweir                 // logic size for impDrawMember call
310cdf0e10cSrcweir                 basegfx::B2DRange aBufferRememberedRangeLogic(
311cdf0e10cSrcweir                     maBufferRememberedRangePixel.getMinX(), maBufferRememberedRangePixel.getMinY(),
312cdf0e10cSrcweir                     maBufferRememberedRangePixel.getMaxX(), maBufferRememberedRangePixel.getMaxY());
313cdf0e10cSrcweir                 aBufferRememberedRangeLogic.transform(getOutputDevice().GetInverseViewTransformation());
314cdf0e10cSrcweir 
315cdf0e10cSrcweir                 // prepare cursor handling
316cdf0e10cSrcweir                 const bool bTargetIsWindow(OUTDEV_WINDOW == rmOutputDevice.GetOutDevType());
317cdf0e10cSrcweir                 bool bCursorWasEnabled(false);
318cdf0e10cSrcweir 
319cdf0e10cSrcweir                 // #i80730# switch off VCL cursor during overlay refresh
320cdf0e10cSrcweir                 if(bTargetIsWindow)
321cdf0e10cSrcweir                 {
322cdf0e10cSrcweir                     Window& rWindow = static_cast< Window& >(rmOutputDevice);
323cdf0e10cSrcweir                     Cursor* pCursor = rWindow.GetCursor();
324cdf0e10cSrcweir 
325cdf0e10cSrcweir                     if(pCursor && pCursor->IsVisible())
326cdf0e10cSrcweir                     {
327cdf0e10cSrcweir                         pCursor->Hide();
328cdf0e10cSrcweir                         bCursorWasEnabled = true;
329cdf0e10cSrcweir                     }
330cdf0e10cSrcweir                 }
331cdf0e10cSrcweir 
332cdf0e10cSrcweir                 if(DoRefreshWithPreRendering())
333cdf0e10cSrcweir                 {
334cdf0e10cSrcweir                     // #i73602# ensure valid and sized maOutputBufferDevice
335cdf0e10cSrcweir                     const Size aDestinationSizePixel(maBufferDevice.GetOutputSizePixel());
336cdf0e10cSrcweir                     const Size aOutputBufferSizePixel(maOutputBufferDevice.GetOutputSizePixel());
337cdf0e10cSrcweir 
338cdf0e10cSrcweir                     if(aDestinationSizePixel != aOutputBufferSizePixel)
339cdf0e10cSrcweir                     {
340cdf0e10cSrcweir                         maOutputBufferDevice.SetOutputSizePixel(aDestinationSizePixel);
341cdf0e10cSrcweir                     }
342cdf0e10cSrcweir 
343cdf0e10cSrcweir                     maOutputBufferDevice.SetMapMode(getOutputDevice().GetMapMode());
344cdf0e10cSrcweir                     maOutputBufferDevice.EnableMapMode(false);
345cdf0e10cSrcweir                     maOutputBufferDevice.SetDrawMode(maBufferDevice.GetDrawMode());
346cdf0e10cSrcweir                     maOutputBufferDevice.SetSettings(maBufferDevice.GetSettings());
347cdf0e10cSrcweir                     maOutputBufferDevice.SetAntialiasing(maBufferDevice.GetAntialiasing());
348cdf0e10cSrcweir 
349cdf0e10cSrcweir                     // calculate sizes
350cdf0e10cSrcweir                     Rectangle aRegionRectanglePixel(
351cdf0e10cSrcweir                         maBufferRememberedRangePixel.getMinX(), maBufferRememberedRangePixel.getMinY(),
352cdf0e10cSrcweir                         maBufferRememberedRangePixel.getMaxX(), maBufferRememberedRangePixel.getMaxY());
353cdf0e10cSrcweir 
354cdf0e10cSrcweir                     // truncate aRegionRectanglePixel to destination pixel size, more does
355cdf0e10cSrcweir                     // not need to be prepared since destination is a buffer for a window. So,
356cdf0e10cSrcweir                     // maximum size indirectly shall be limited to getOutputDevice().GetOutputSizePixel()
357cdf0e10cSrcweir                     if(aRegionRectanglePixel.Left() < 0L)
358cdf0e10cSrcweir                     {
359cdf0e10cSrcweir                         aRegionRectanglePixel.Left() = 0L;
360cdf0e10cSrcweir                     }
361cdf0e10cSrcweir 
362cdf0e10cSrcweir                     if(aRegionRectanglePixel.Top() < 0L)
363cdf0e10cSrcweir                     {
364cdf0e10cSrcweir                         aRegionRectanglePixel.Top() = 0L;
365cdf0e10cSrcweir                     }
366cdf0e10cSrcweir 
367cdf0e10cSrcweir                     if(aRegionRectanglePixel.Right() > aDestinationSizePixel.getWidth())
368cdf0e10cSrcweir                     {
369cdf0e10cSrcweir                         aRegionRectanglePixel.Right() = aDestinationSizePixel.getWidth();
370cdf0e10cSrcweir                     }
371cdf0e10cSrcweir 
372cdf0e10cSrcweir                     if(aRegionRectanglePixel.Bottom() > aDestinationSizePixel.getHeight())
373cdf0e10cSrcweir                     {
374cdf0e10cSrcweir                         aRegionRectanglePixel.Bottom() = aDestinationSizePixel.getHeight();
375cdf0e10cSrcweir                     }
376cdf0e10cSrcweir 
377cdf0e10cSrcweir                     // get sizes
378cdf0e10cSrcweir                     const Point aTopLeft(aRegionRectanglePixel.TopLeft());
379cdf0e10cSrcweir                     const Size aSize(aRegionRectanglePixel.GetSize());
380cdf0e10cSrcweir 
381cdf0e10cSrcweir                     {
382cdf0e10cSrcweir                         const bool bMapModeWasEnabledDest(maBufferDevice.IsMapModeEnabled());
383cdf0e10cSrcweir                         maBufferDevice.EnableMapMode(false);
384cdf0e10cSrcweir 
385cdf0e10cSrcweir                         maOutputBufferDevice.DrawOutDev(
386cdf0e10cSrcweir                             aTopLeft, aSize, // destination
387cdf0e10cSrcweir                             aTopLeft, aSize, // source
388cdf0e10cSrcweir                             maBufferDevice);
389cdf0e10cSrcweir 
390cdf0e10cSrcweir                         // restore MapModes
391cdf0e10cSrcweir                         maBufferDevice.EnableMapMode(bMapModeWasEnabledDest);
392cdf0e10cSrcweir                     }
393cdf0e10cSrcweir 
394cdf0e10cSrcweir                     // paint overlay content for remembered region, use
395cdf0e10cSrcweir                     // method from base class directly
396cdf0e10cSrcweir                     maOutputBufferDevice.EnableMapMode(true);
397cdf0e10cSrcweir                     OverlayManager::ImpDrawMembers(aBufferRememberedRangeLogic, maOutputBufferDevice);
398cdf0e10cSrcweir                     maOutputBufferDevice.EnableMapMode(false);
399cdf0e10cSrcweir 
400cdf0e10cSrcweir                     // copy to output
401cdf0e10cSrcweir                     {
402cdf0e10cSrcweir                         const bool bMapModeWasEnabledDest(getOutputDevice().IsMapModeEnabled());
403cdf0e10cSrcweir                         getOutputDevice().EnableMapMode(false);
404cdf0e10cSrcweir 
405cdf0e10cSrcweir                         getOutputDevice().DrawOutDev(
406cdf0e10cSrcweir                             aTopLeft, aSize, // destination
407cdf0e10cSrcweir                             aTopLeft, aSize, // source
408cdf0e10cSrcweir                             maOutputBufferDevice);
409cdf0e10cSrcweir 
410cdf0e10cSrcweir                         // debug
411cdf0e10cSrcweir                         /*getOutputDevice().SetLineColor(COL_RED);
412cdf0e10cSrcweir                         getOutputDevice().SetFillColor();
413cdf0e10cSrcweir                         getOutputDevice().DrawRect(Rectangle(aTopLeft, aSize));*/
414cdf0e10cSrcweir 
415cdf0e10cSrcweir                         // restore MapModes
416cdf0e10cSrcweir                         getOutputDevice().EnableMapMode(bMapModeWasEnabledDest);
417cdf0e10cSrcweir                     }
418cdf0e10cSrcweir                 }
419cdf0e10cSrcweir                 else
420cdf0e10cSrcweir                 {
421cdf0e10cSrcweir                     // Restore all rectangles for remembered region from buffer
422cdf0e10cSrcweir                     ImpRestoreBackground();
423cdf0e10cSrcweir 
424cdf0e10cSrcweir                     // paint overlay content for remembered region, use
425cdf0e10cSrcweir                     // method from base class directly
426cdf0e10cSrcweir                     OverlayManager::ImpDrawMembers(aBufferRememberedRangeLogic, getOutputDevice());
427cdf0e10cSrcweir                 }
428cdf0e10cSrcweir 
429cdf0e10cSrcweir                 // VCL hack for transparent child windows
430cdf0e10cSrcweir                 // Problem is e.g. a radiobuttion form control in life mode. The used window
431*07ec2daeSmseidel                 // is a transparent vcl childwindow. This flag only allows the parent window to
432cdf0e10cSrcweir                 // paint into the child windows area, but there is no mechanism which takes
433cdf0e10cSrcweir                 // care for a repaint of the child window. A transparent child window is NOT
434*07ec2daeSmseidel                 // a window which always keeps its content consistent over the parent, but it's
435cdf0e10cSrcweir                 // more like just a paint flag for the parent.
436*07ec2daeSmseidel                 // To get the update, the windows in question are updated manually here.
437cdf0e10cSrcweir                 if(bTargetIsWindow)
438cdf0e10cSrcweir                 {
439cdf0e10cSrcweir                     Window& rWindow = static_cast< Window& >(rmOutputDevice);
440cdf0e10cSrcweir 
441cdf0e10cSrcweir                     if(rWindow.IsChildTransparentModeEnabled() && rWindow.GetChildCount())
442cdf0e10cSrcweir                     {
443cdf0e10cSrcweir                         const Rectangle aRegionRectanglePixel(
444cdf0e10cSrcweir                             maBufferRememberedRangePixel.getMinX(), maBufferRememberedRangePixel.getMinY(),
445cdf0e10cSrcweir                             maBufferRememberedRangePixel.getMaxX(), maBufferRememberedRangePixel.getMaxY());
446cdf0e10cSrcweir 
447cdf0e10cSrcweir                         for(sal_uInt16 a(0); a < rWindow.GetChildCount(); a++)
448cdf0e10cSrcweir                         {
449cdf0e10cSrcweir                             Window* pCandidate = rWindow.GetChild(a);
450cdf0e10cSrcweir 
451cdf0e10cSrcweir                             if(pCandidate && pCandidate->IsPaintTransparent())
452cdf0e10cSrcweir                             {
453cdf0e10cSrcweir                                 const Rectangle aCandidatePosSizePixel(pCandidate->GetPosPixel(), pCandidate->GetSizePixel());
454cdf0e10cSrcweir 
455cdf0e10cSrcweir                                 if(aCandidatePosSizePixel.IsOver(aRegionRectanglePixel))
456cdf0e10cSrcweir                                 {
457cdf0e10cSrcweir                                     pCandidate->Invalidate(INVALIDATE_NOTRANSPARENT|INVALIDATE_CHILDREN);
458cdf0e10cSrcweir                                     pCandidate->Update();
459cdf0e10cSrcweir                                 }
460cdf0e10cSrcweir                             }
461cdf0e10cSrcweir                         }
462cdf0e10cSrcweir                     }
463cdf0e10cSrcweir                 }
464cdf0e10cSrcweir 
465cdf0e10cSrcweir                 // #i80730# restore visibility of VCL cursor
466cdf0e10cSrcweir                 if(bCursorWasEnabled)
467cdf0e10cSrcweir                 {
468cdf0e10cSrcweir                     Window& rWindow = static_cast< Window& >(rmOutputDevice);
469cdf0e10cSrcweir                     Cursor* pCursor = rWindow.GetCursor();
470cdf0e10cSrcweir 
471cdf0e10cSrcweir                     if(pCursor)
472cdf0e10cSrcweir                     {
473cdf0e10cSrcweir                         // check if cursor still exists. It may have been deleted from someone
474cdf0e10cSrcweir                         pCursor->Show();
475cdf0e10cSrcweir                     }
476cdf0e10cSrcweir                 }
477cdf0e10cSrcweir 
478cdf0e10cSrcweir                 // forget remembered Region
479cdf0e10cSrcweir                 maBufferRememberedRangePixel.reset();
480cdf0e10cSrcweir             }
481cdf0e10cSrcweir 
482cdf0e10cSrcweir             return 0;
483cdf0e10cSrcweir         }
484cdf0e10cSrcweir 
OverlayManagerBuffered(OutputDevice & rOutputDevice,bool bRefreshWithPreRendering)485cdf0e10cSrcweir         OverlayManagerBuffered::OverlayManagerBuffered(
486cdf0e10cSrcweir             OutputDevice& rOutputDevice,
487cdf0e10cSrcweir             bool bRefreshWithPreRendering)
488a56bd57bSArmin Le Grand         :   OverlayManager(rOutputDevice),
489cdf0e10cSrcweir             mbRefreshWithPreRendering(bRefreshWithPreRendering)
490cdf0e10cSrcweir         {
491cdf0e10cSrcweir             // Init timer
492cdf0e10cSrcweir             maBufferTimer.SetTimeout(1);
493cdf0e10cSrcweir             maBufferTimer.SetTimeoutHdl(LINK(this, OverlayManagerBuffered, ImpBufferTimerHandler));
494cdf0e10cSrcweir         }
495cdf0e10cSrcweir 
~OverlayManagerBuffered()496cdf0e10cSrcweir         OverlayManagerBuffered::~OverlayManagerBuffered()
497cdf0e10cSrcweir         {
498cdf0e10cSrcweir             // Clear timer
499cdf0e10cSrcweir             maBufferTimer.Stop();
500cdf0e10cSrcweir 
501cdf0e10cSrcweir             if(!maBufferRememberedRangePixel.isEmpty())
502cdf0e10cSrcweir             {
503cdf0e10cSrcweir                 // Restore all rectangles for remembered region from buffer
504cdf0e10cSrcweir                 ImpRestoreBackground();
505cdf0e10cSrcweir             }
506cdf0e10cSrcweir         }
507cdf0e10cSrcweir 
completeRedraw(const Region & rRegion,OutputDevice * pPreRenderDevice) const508cdf0e10cSrcweir         void OverlayManagerBuffered::completeRedraw(const Region& rRegion, OutputDevice* pPreRenderDevice) const
509cdf0e10cSrcweir         {
510cdf0e10cSrcweir             if(!rRegion.IsEmpty())
511cdf0e10cSrcweir             {
512cdf0e10cSrcweir                 // save new background
513cdf0e10cSrcweir                 ((OverlayManagerBuffered*)this)->ImpSaveBackground(rRegion, pPreRenderDevice);
514cdf0e10cSrcweir             }
515cdf0e10cSrcweir 
516cdf0e10cSrcweir             // call parent
517cdf0e10cSrcweir             OverlayManager::completeRedraw(rRegion, pPreRenderDevice);
518cdf0e10cSrcweir         }
519cdf0e10cSrcweir 
flush()520cdf0e10cSrcweir         void OverlayManagerBuffered::flush()
521cdf0e10cSrcweir         {
522cdf0e10cSrcweir             // call timer handler direct
523cdf0e10cSrcweir             ImpBufferTimerHandler(0);
524cdf0e10cSrcweir         }
525cdf0e10cSrcweir 
526cdf0e10cSrcweir         // #i68597# part of content gets copied, react on it
copyArea(const Point & rDestPt,const Point & rSrcPt,const Size & rSrcSize)527cdf0e10cSrcweir         void OverlayManagerBuffered::copyArea(const Point& rDestPt, const Point& rSrcPt, const Size& rSrcSize)
528cdf0e10cSrcweir         {
529cdf0e10cSrcweir             // scroll local buffered area
530cdf0e10cSrcweir             maBufferDevice.CopyArea(rDestPt, rSrcPt, rSrcSize);
531cdf0e10cSrcweir         }
532cdf0e10cSrcweir 
restoreBackground(const Region & rRegion) const533cdf0e10cSrcweir         void OverlayManagerBuffered::restoreBackground(const Region& rRegion) const
534cdf0e10cSrcweir         {
535cdf0e10cSrcweir             // restore
536cdf0e10cSrcweir             const Region aRegionPixel(getOutputDevice().LogicToPixel(rRegion));
537cdf0e10cSrcweir             ImpRestoreBackground(aRegionPixel);
538cdf0e10cSrcweir 
539cdf0e10cSrcweir             // call parent
540cdf0e10cSrcweir             OverlayManager::restoreBackground(rRegion);
541cdf0e10cSrcweir         }
542cdf0e10cSrcweir 
invalidateRange(const basegfx::B2DRange & rRange)543cdf0e10cSrcweir         void OverlayManagerBuffered::invalidateRange(const basegfx::B2DRange& rRange)
544cdf0e10cSrcweir         {
545cdf0e10cSrcweir             if(!rRange.isEmpty())
546cdf0e10cSrcweir             {
547cdf0e10cSrcweir                 // buffered output, do not invalidate but use the timer
548cdf0e10cSrcweir                 // to trigger a timer event for refresh
549cdf0e10cSrcweir                 maBufferTimer.Start();
550cdf0e10cSrcweir 
551cdf0e10cSrcweir                 // add the discrete range to the remembered region
552cdf0e10cSrcweir                 // #i75163# use double precision and floor/ceil rounding to get overlapped pixel region, even
553cdf0e10cSrcweir                 // when the given logic region has a width/height of 0.0. This does NOT work with LogicToPixel
554cdf0e10cSrcweir                 // since it just transforms the top left and bottom right points equally without taking
555cdf0e10cSrcweir                 // discrete pixel coverage into account. An empty B2DRange and thus empty logic Rectangle translated
556cdf0e10cSrcweir                 // to an also empty discrete pixel rectangle - what is wrong.
557cdf0e10cSrcweir                 basegfx::B2DRange aDiscreteRange(rRange);
558cdf0e10cSrcweir                 aDiscreteRange.transform(getOutputDevice().GetViewTransformation());
559cdf0e10cSrcweir 
560cdf0e10cSrcweir                 if(maDrawinglayerOpt.IsAntiAliasing())
561cdf0e10cSrcweir                 {
562cdf0e10cSrcweir                     // assume AA needs one pixel more and invalidate one pixel more
563cdf0e10cSrcweir                     const double fDiscreteOne(getDiscreteOne());
564cdf0e10cSrcweir                     const basegfx::B2IPoint aTopLeft(
565cdf0e10cSrcweir                         (sal_Int32)floor(aDiscreteRange.getMinX() - fDiscreteOne),
566cdf0e10cSrcweir                         (sal_Int32)floor(aDiscreteRange.getMinY() - fDiscreteOne));
567cdf0e10cSrcweir                     const basegfx::B2IPoint aBottomRight(
568cdf0e10cSrcweir                         (sal_Int32)ceil(aDiscreteRange.getMaxX() + fDiscreteOne),
569cdf0e10cSrcweir                         (sal_Int32)ceil(aDiscreteRange.getMaxY() + fDiscreteOne));
570cdf0e10cSrcweir 
571cdf0e10cSrcweir                     maBufferRememberedRangePixel.expand(aTopLeft);
572cdf0e10cSrcweir                     maBufferRememberedRangePixel.expand(aBottomRight);
573cdf0e10cSrcweir                 }
574cdf0e10cSrcweir                 else
575cdf0e10cSrcweir                 {
576cdf0e10cSrcweir                     const basegfx::B2IPoint aTopLeft((sal_Int32)floor(aDiscreteRange.getMinX()), (sal_Int32)floor(aDiscreteRange.getMinY()));
577cdf0e10cSrcweir                     const basegfx::B2IPoint aBottomRight((sal_Int32)ceil(aDiscreteRange.getMaxX()), (sal_Int32)ceil(aDiscreteRange.getMaxY()));
578cdf0e10cSrcweir 
579cdf0e10cSrcweir                     maBufferRememberedRangePixel.expand(aTopLeft);
580cdf0e10cSrcweir                     maBufferRememberedRangePixel.expand(aBottomRight);
581cdf0e10cSrcweir                 }
582cdf0e10cSrcweir             }
583cdf0e10cSrcweir         }
584cdf0e10cSrcweir 
SetRefreshWithPreRendering(bool bNew)585cdf0e10cSrcweir         void OverlayManagerBuffered::SetRefreshWithPreRendering(bool bNew)
586cdf0e10cSrcweir         {
587cdf0e10cSrcweir             if((bool)mbRefreshWithPreRendering != bNew)
588cdf0e10cSrcweir             {
589cdf0e10cSrcweir                 mbRefreshWithPreRendering = bNew;
590cdf0e10cSrcweir             }
591cdf0e10cSrcweir         }
592cdf0e10cSrcweir     } // end of namespace overlay
593cdf0e10cSrcweir } // end of namespace sdr
594cdf0e10cSrcweir 
595*07ec2daeSmseidel /* vim: set noet sw=4 ts=4: */
596