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