xref: /trunk/main/svx/source/svdraw/sdrpaintwindow.cxx (revision af7f2cbf3d6a5481a2f45e7fae5e85a32449c47d)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_svx.hxx"
26 #include <svx/sdrpaintwindow.hxx>
27 #include <svx/sdr/overlay/overlaymanagerbuffered.hxx>
28 #include <svx/svdpntv.hxx>
29 #include <vcl/gdimtf.hxx>
30 #include <vcl/svapp.hxx>
31 
32 
33 SdrPreRenderDevice::SdrPreRenderDevice(OutputDevice& rOriginal)
34 :   mrOutputDevice(rOriginal)
35 {
36 }
37 
38 SdrPreRenderDevice::~SdrPreRenderDevice()
39 {
40 }
41 
42 void SdrPreRenderDevice::PreparePreRenderDevice()
43 {
44     // compare size of maPreRenderDevice with size of visible area
45     if(maPreRenderDevice.GetOutputSizePixel() != mrOutputDevice.GetOutputSizePixel())
46     {
47         maPreRenderDevice.SetOutputSizePixel(mrOutputDevice.GetOutputSizePixel());
48     }
49 
50     // Also compare the MapModes for zoom/scroll changes
51     if(maPreRenderDevice.GetMapMode() != mrOutputDevice.GetMapMode())
52     {
53         maPreRenderDevice.SetMapMode(mrOutputDevice.GetMapMode());
54     }
55 
56     // #i29186#
57     maPreRenderDevice.SetDrawMode(mrOutputDevice.GetDrawMode());
58     maPreRenderDevice.SetSettings(mrOutputDevice.GetSettings());
59 }
60 
61 void SdrPreRenderDevice::OutputPreRenderDevice(const Region& rExpandedRegion)
62 {
63     // region to pixels
64     const Region aRegionPixel(mrOutputDevice.LogicToPixel(rExpandedRegion));
65     //RegionHandle aRegionHandle(aRegionPixel.BeginEnumRects());
66     //Rectangle aRegionRectanglePixel;
67 
68     // MapModes off
69     sal_Bool bMapModeWasEnabledDest(mrOutputDevice.IsMapModeEnabled());
70     sal_Bool bMapModeWasEnabledSource(maPreRenderDevice.IsMapModeEnabled());
71     mrOutputDevice.EnableMapMode(sal_False);
72     maPreRenderDevice.EnableMapMode(sal_False);
73 
74     RectangleVector aRectangles;
75     aRegionPixel.GetRegionRectangles(aRectangles);
76 
77     for(RectangleVector::const_iterator aRectIter(aRectangles.begin()); aRectIter != aRectangles.end(); aRectIter++)
78     {
79         // for each rectangle, copy the area
80         const Point aTopLeft(aRectIter->TopLeft());
81         const Size aSize(aRectIter->GetSize());
82 
83         mrOutputDevice.DrawOutDev(
84             aTopLeft, aSize,
85             aTopLeft, aSize,
86             maPreRenderDevice);
87 
88 #ifdef DBG_UTIL
89         // #i74769#
90         static bool bDoPaintForVisualControlRegion(false);
91 
92         if(bDoPaintForVisualControlRegion)
93         {
94             const Color aColor((((((rand()&0x7f)|0x80)<<8L)|((rand()&0x7f)|0x80))<<8L)|((rand()&0x7f)|0x80));
95 
96             mrOutputDevice.SetLineColor(aColor);
97             mrOutputDevice.SetFillColor();
98             mrOutputDevice.DrawRect(*aRectIter);
99         }
100 #endif
101     }
102 
103 //  while(aRegionPixel.GetEnumRects(aRegionHandle, aRegionRectanglePixel))
104 //  {
105 //      // for each rectangle, copy the area
106 //      const Point aTopLeft(aRegionRectanglePixel.TopLeft());
107 //      const Size aSize(aRegionRectanglePixel.GetSize());
108 //
109 //      mrOutputDevice.DrawOutDev(
110 //          aTopLeft, aSize,
111 //          aTopLeft, aSize,
112 //          maPreRenderDevice);
113 //
114 //#ifdef DBG_UTIL
115 //      // #i74769#
116 //      static bool bDoPaintForVisualControlRegion(false);
117 //      if(bDoPaintForVisualControlRegion)
118 //      {
119 //          Color aColor((((((rand()&0x7f)|0x80)<<8L)|((rand()&0x7f)|0x80))<<8L)|((rand()&0x7f)|0x80));
120 //          mrOutputDevice.SetLineColor(aColor);
121 //          mrOutputDevice.SetFillColor();
122 //          mrOutputDevice.DrawRect(aRegionRectanglePixel);
123 //      }
124 //#endif
125 //  }
126 //
127 //  aRegionPixel.EndEnumRects(aRegionHandle);
128 
129     mrOutputDevice.EnableMapMode(bMapModeWasEnabledDest);
130     maPreRenderDevice.EnableMapMode(bMapModeWasEnabledSource);
131 }
132 
133 
134 void SdrPaintWindow::impCreateOverlayManager()
135 {
136     // not yet one created?
137     if(!mpOverlayManager)
138     {
139         // is it a window?
140         if(OUTDEV_WINDOW == GetOutputDevice().GetOutDevType())
141         {
142             // decide which OverlayManager to use
143             if(GetPaintView().IsBufferedOverlayAllowed() && mbUseBuffer)
144             {
145                 // buffered OverlayManager, buffers its background and refreshes from there
146                 // for pure overlay changes (no system redraw). The 3rd parameter specifies
147                 // if that refresh itself will use a 2nd vdev to avoid flickering.
148                 // Also hand over the evtl. existing old OverlayManager; this means to take over
149                 // the registered OverlayObjects from it
150                 mpOverlayManager = new ::sdr::overlay::OverlayManagerBuffered(GetOutputDevice(), true);
151             }
152             else
153             {
154                 // unbuffered OverlayManager, just invalidates places where changes
155                 // take place
156                 // Also hand over the evtl. existing old OverlayManager; this means to take over
157                 // the registered OverlayObjects from it
158                 mpOverlayManager = new ::sdr::overlay::OverlayManager(GetOutputDevice());
159             }
160 
161             OSL_ENSURE(mpOverlayManager, "SdrPaintWindow::SdrPaintWindow: Could not allocate an overlayManager (!)");
162 
163             // Request a repaint so that the buffered overlay manager fills
164             // its buffer properly. This is a workaround for missing buffer
165             // updates.
166             Window* pWindow = dynamic_cast<Window*>(&GetOutputDevice());
167             if (pWindow != NULL)
168                 pWindow->Invalidate();
169 
170             Color aColA(GetPaintView().getOptionsDrawinglayer().GetStripeColorA());
171             Color aColB(GetPaintView().getOptionsDrawinglayer().GetStripeColorB());
172 
173             if(Application::GetSettings().GetStyleSettings().GetHighContrastMode())
174             {
175                 aColA = aColB = Application::GetSettings().GetStyleSettings().GetHighlightColor();
176                 aColB.Invert();
177             }
178 
179             mpOverlayManager->setStripeColorA(aColA);
180             mpOverlayManager->setStripeColorB(aColB);
181             mpOverlayManager->setStripeLengthPixel(GetPaintView().getOptionsDrawinglayer().GetStripeLength());
182         }
183     }
184 }
185 
186 SdrPaintWindow::SdrPaintWindow(SdrPaintView& rNewPaintView, OutputDevice& rOut)
187 :   mrOutputDevice(rOut),
188     mrPaintView(rNewPaintView),
189     mpOverlayManager(0L),
190     mpPreRenderDevice(0L),
191     mbTemporaryTarget(false), // #i72889#
192     mbUseBuffer(true)
193 {
194 }
195 
196 SdrPaintWindow::~SdrPaintWindow()
197 {
198     if(mpOverlayManager)
199     {
200         delete mpOverlayManager;
201         mpOverlayManager = 0L;
202     }
203 
204     DestroyPreRenderDevice();
205 }
206 
207 ::sdr::overlay::OverlayManager* SdrPaintWindow::GetOverlayManager() const
208 {
209     if(!mpOverlayManager)
210     {
211         // Create buffered overlay manager by default.
212         const_cast< SdrPaintWindow* >(this)->impCreateOverlayManager();
213     }
214 
215     return mpOverlayManager;
216 }
217 
218 Rectangle SdrPaintWindow::GetVisibleArea() const
219 {
220     Size aVisSizePixel(GetOutputDevice().GetOutputSizePixel());
221     return Rectangle(GetOutputDevice().PixelToLogic(Rectangle(Point(0,0), aVisSizePixel)));
222 }
223 
224 sal_Bool SdrPaintWindow::OutputToRecordingMetaFile() const
225 {
226     GDIMetaFile* pMetaFile = mrOutputDevice.GetConnectMetaFile();
227     return (pMetaFile && pMetaFile->IsRecord() && !pMetaFile->IsPause());
228 }
229 
230 void SdrPaintWindow::PreparePreRenderDevice()
231 {
232     const sal_Bool bPrepareBufferedOutput(
233         mrPaintView.IsBufferedOutputAllowed()
234         && !OutputToPrinter()
235         && !OutputToVirtualDevice()
236         && !OutputToRecordingMetaFile());
237 
238     if(bPrepareBufferedOutput)
239     {
240         if(!mpPreRenderDevice)
241         {
242             mpPreRenderDevice = new SdrPreRenderDevice(mrOutputDevice);
243         }
244     }
245     else
246     {
247         DestroyPreRenderDevice();
248     }
249 
250     if(mpPreRenderDevice)
251     {
252         mpPreRenderDevice->PreparePreRenderDevice();
253     }
254 }
255 
256 void SdrPaintWindow::DestroyPreRenderDevice()
257 {
258     if(mpPreRenderDevice)
259     {
260         delete mpPreRenderDevice;
261         mpPreRenderDevice = 0L;
262     }
263 }
264 
265 void SdrPaintWindow::OutputPreRenderDevice(const Region& rExpandedRegion)
266 {
267     if(mpPreRenderDevice)
268     {
269         mpPreRenderDevice->OutputPreRenderDevice(rExpandedRegion);
270     }
271 }
272 
273 // #i73602# add flag if buffer shall be used
274 void SdrPaintWindow::DrawOverlay(const Region& rRegion)
275 {
276     // ## force creation of OverlayManager since the first repaint needs to
277     // save the background to get a controlled start into overlay mechanism
278     impCreateOverlayManager();
279 
280     if(mpOverlayManager && !OutputToPrinter())
281     {
282         if(mpPreRenderDevice)
283         {
284             mpOverlayManager->completeRedraw(rRegion, &mpPreRenderDevice->GetPreRenderDevice());
285         }
286         else
287         {
288             mpOverlayManager->completeRedraw(rRegion);
289         }
290     }
291 }
292 
293 void SdrPaintWindow::HideOverlay(const Region& rRegion)
294 {
295     if(mpOverlayManager && !OutputToPrinter())
296     {
297         if(!mpPreRenderDevice)
298         {
299             mpOverlayManager->restoreBackground(rRegion);
300         }
301     }
302 }
303 
304 const Region& SdrPaintWindow::GetRedrawRegion() const
305 {
306     return maRedrawRegion;
307 }
308 
309 void SdrPaintWindow::SetRedrawRegion(const Region& rNew)
310 {
311     maRedrawRegion = rNew;
312 }
313 
314 /* vim: set noet sw=4 ts=4: */
315