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(OutputDevice & rOriginal)34 SdrPreRenderDevice::SdrPreRenderDevice(OutputDevice& rOriginal)
35 : mrOutputDevice(rOriginal)
36 {
37 }
38
~SdrPreRenderDevice()39 SdrPreRenderDevice::~SdrPreRenderDevice()
40 {
41 }
42
PreparePreRenderDevice()43 void SdrPreRenderDevice::PreparePreRenderDevice()
44 {
45 // compare size of maPreRenderDevice with size of visible area
46 if(maPreRenderDevice.GetOutputSizePixel() != mrOutputDevice.GetOutputSizePixel())
47 {
48 maPreRenderDevice.SetOutputSizePixel(mrOutputDevice.GetOutputSizePixel());
49 }
50
51 // Also compare the MapModes for zoom/scroll changes
52 if(maPreRenderDevice.GetMapMode() != mrOutputDevice.GetMapMode())
53 {
54 maPreRenderDevice.SetMapMode(mrOutputDevice.GetMapMode());
55 }
56
57 // #i29186#
58 maPreRenderDevice.SetDrawMode(mrOutputDevice.GetDrawMode());
59 maPreRenderDevice.SetSettings(mrOutputDevice.GetSettings());
60 }
61
OutputPreRenderDevice(const Region & rExpandedRegion)62 void SdrPreRenderDevice::OutputPreRenderDevice(const Region& rExpandedRegion)
63 {
64 // region to pixels
65 const Region aRegionPixel(mrOutputDevice.LogicToPixel(rExpandedRegion));
66 //RegionHandle aRegionHandle(aRegionPixel.BeginEnumRects());
67 //Rectangle aRegionRectanglePixel;
68
69 // MapModes off
70 sal_Bool bMapModeWasEnabledDest(mrOutputDevice.IsMapModeEnabled());
71 sal_Bool bMapModeWasEnabledSource(maPreRenderDevice.IsMapModeEnabled());
72 mrOutputDevice.EnableMapMode(sal_False);
73 maPreRenderDevice.EnableMapMode(sal_False);
74
75 RectangleVector aRectangles;
76 aRegionPixel.GetRegionRectangles(aRectangles);
77
78 for(RectangleVector::const_iterator aRectIter(aRectangles.begin()); aRectIter != aRectangles.end(); aRectIter++)
79 {
80 // for each rectangle, copy the area
81 const Point aTopLeft(aRectIter->TopLeft());
82 const Size aSize(aRectIter->GetSize());
83
84 mrOutputDevice.DrawOutDev(
85 aTopLeft, aSize,
86 aTopLeft, aSize,
87 maPreRenderDevice);
88
89 #ifdef DBG_UTIL
90 // #i74769#
91 static bool bDoPaintForVisualControlRegion(false);
92
93 if(bDoPaintForVisualControlRegion)
94 {
95 const Color aColor((((((rand()&0x7f)|0x80)<<8L)|((rand()&0x7f)|0x80))<<8L)|((rand()&0x7f)|0x80));
96
97 mrOutputDevice.SetLineColor(aColor);
98 mrOutputDevice.SetFillColor();
99 mrOutputDevice.DrawRect(*aRectIter);
100 }
101 #endif
102 }
103
104 // while(aRegionPixel.GetEnumRects(aRegionHandle, aRegionRectanglePixel))
105 // {
106 // // for each rectangle, copy the area
107 // const Point aTopLeft(aRegionRectanglePixel.TopLeft());
108 // const Size aSize(aRegionRectanglePixel.GetSize());
109 //
110 // mrOutputDevice.DrawOutDev(
111 // aTopLeft, aSize,
112 // aTopLeft, aSize,
113 // maPreRenderDevice);
114 //
115 //#ifdef DBG_UTIL
116 // // #i74769#
117 // static bool bDoPaintForVisualControlRegion(false);
118 // if(bDoPaintForVisualControlRegion)
119 // {
120 // Color aColor((((((rand()&0x7f)|0x80)<<8L)|((rand()&0x7f)|0x80))<<8L)|((rand()&0x7f)|0x80));
121 // mrOutputDevice.SetLineColor(aColor);
122 // mrOutputDevice.SetFillColor();
123 // mrOutputDevice.DrawRect(aRegionRectanglePixel);
124 // }
125 //#endif
126 // }
127 //
128 // aRegionPixel.EndEnumRects(aRegionHandle);
129
130 mrOutputDevice.EnableMapMode(bMapModeWasEnabledDest);
131 maPreRenderDevice.EnableMapMode(bMapModeWasEnabledSource);
132 }
133
134 ////////////////////////////////////////////////////////////////////////////////////////////////////
135
impCreateOverlayManager()136 void SdrPaintWindow::impCreateOverlayManager()
137 {
138 // not yet one created?
139 if(!mpOverlayManager)
140 {
141 // is it a window?
142 if(OUTDEV_WINDOW == GetOutputDevice().GetOutDevType())
143 {
144 // decide which OverlayManager to use
145 if(GetPaintView().IsBufferedOverlayAllowed() && mbUseBuffer)
146 {
147 // buffered OverlayManager, buffers it's background and refreshes from there
148 // for pure overlay changes (no system redraw). The 3rd parameter specifies
149 // if that refresh itself will use a 2nd vdev to avoid flickering.
150 // Also hand over the evtl. existing old OverlayManager; this means to take over
151 // the registered OverlayObjects from it
152 mpOverlayManager = new ::sdr::overlay::OverlayManagerBuffered(GetOutputDevice(), true);
153 }
154 else
155 {
156 // unbuffered OverlayManager, just invalidates places where changes
157 // take place
158 // Also hand over the evtl. existing old OverlayManager; this means to take over
159 // the registered OverlayObjects from it
160 mpOverlayManager = new ::sdr::overlay::OverlayManager(GetOutputDevice());
161 }
162
163 OSL_ENSURE(mpOverlayManager, "SdrPaintWindow::SdrPaintWindow: Could not allocate an overlayManager (!)");
164
165 // Request a repaint so that the buffered overlay manager fills
166 // its buffer properly. This is a workaround for missing buffer
167 // updates.
168 Window* pWindow = dynamic_cast<Window*>(&GetOutputDevice());
169 if (pWindow != NULL)
170 pWindow->Invalidate();
171
172 Color aColA(GetPaintView().getOptionsDrawinglayer().GetStripeColorA());
173 Color aColB(GetPaintView().getOptionsDrawinglayer().GetStripeColorB());
174
175 if(Application::GetSettings().GetStyleSettings().GetHighContrastMode())
176 {
177 aColA = aColB = Application::GetSettings().GetStyleSettings().GetHighlightColor();
178 aColB.Invert();
179 }
180
181 mpOverlayManager->setStripeColorA(aColA);
182 mpOverlayManager->setStripeColorB(aColB);
183 mpOverlayManager->setStripeLengthPixel(GetPaintView().getOptionsDrawinglayer().GetStripeLength());
184 }
185 }
186 }
187
SdrPaintWindow(SdrPaintView & rNewPaintView,OutputDevice & rOut)188 SdrPaintWindow::SdrPaintWindow(SdrPaintView& rNewPaintView, OutputDevice& rOut)
189 : mrOutputDevice(rOut),
190 mrPaintView(rNewPaintView),
191 mpOverlayManager(0L),
192 mpPreRenderDevice(0L),
193 mbTemporaryTarget(false), // #i72889#
194 mbUseBuffer(true)
195 {
196 }
197
~SdrPaintWindow()198 SdrPaintWindow::~SdrPaintWindow()
199 {
200 if(mpOverlayManager)
201 {
202 delete mpOverlayManager;
203 mpOverlayManager = 0L;
204 }
205
206 DestroyPreRenderDevice();
207 }
208
GetOverlayManager() const209 ::sdr::overlay::OverlayManager* SdrPaintWindow::GetOverlayManager() const
210 {
211 if(!mpOverlayManager)
212 {
213 // Create buffered overlay manager by default.
214 const_cast< SdrPaintWindow* >(this)->impCreateOverlayManager();
215 }
216
217 return mpOverlayManager;
218 }
219
GetVisibleArea() const220 Rectangle SdrPaintWindow::GetVisibleArea() const
221 {
222 Size aVisSizePixel(GetOutputDevice().GetOutputSizePixel());
223 return Rectangle(GetOutputDevice().PixelToLogic(Rectangle(Point(0,0), aVisSizePixel)));
224 }
225
OutputToRecordingMetaFile() const226 sal_Bool SdrPaintWindow::OutputToRecordingMetaFile() const
227 {
228 GDIMetaFile* pMetaFile = mrOutputDevice.GetConnectMetaFile();
229 return (pMetaFile && pMetaFile->IsRecord() && !pMetaFile->IsPause());
230 }
231
PreparePreRenderDevice()232 void SdrPaintWindow::PreparePreRenderDevice()
233 {
234 const sal_Bool bPrepareBufferedOutput(
235 mrPaintView.IsBufferedOutputAllowed()
236 && !OutputToPrinter()
237 && !OutputToVirtualDevice()
238 && !OutputToRecordingMetaFile());
239
240 if(bPrepareBufferedOutput)
241 {
242 if(!mpPreRenderDevice)
243 {
244 mpPreRenderDevice = new SdrPreRenderDevice(mrOutputDevice);
245 }
246 }
247 else
248 {
249 DestroyPreRenderDevice();
250 }
251
252 if(mpPreRenderDevice)
253 {
254 mpPreRenderDevice->PreparePreRenderDevice();
255 }
256 }
257
DestroyPreRenderDevice()258 void SdrPaintWindow::DestroyPreRenderDevice()
259 {
260 if(mpPreRenderDevice)
261 {
262 delete mpPreRenderDevice;
263 mpPreRenderDevice = 0L;
264 }
265 }
266
OutputPreRenderDevice(const Region & rExpandedRegion)267 void SdrPaintWindow::OutputPreRenderDevice(const Region& rExpandedRegion)
268 {
269 if(mpPreRenderDevice)
270 {
271 mpPreRenderDevice->OutputPreRenderDevice(rExpandedRegion);
272 }
273 }
274
275 // #i73602# add flag if buffer shall be used
DrawOverlay(const Region & rRegion)276 void SdrPaintWindow::DrawOverlay(const Region& rRegion)
277 {
278 // ## force creation of OverlayManager since the first repaint needs to
279 // save the background to get a controlled start into overlay mechanism
280 impCreateOverlayManager();
281
282 if(mpOverlayManager && !OutputToPrinter())
283 {
284 if(mpPreRenderDevice)
285 {
286 mpOverlayManager->completeRedraw(rRegion, &mpPreRenderDevice->GetPreRenderDevice());
287 }
288 else
289 {
290 mpOverlayManager->completeRedraw(rRegion);
291 }
292 }
293 }
294
HideOverlay(const Region & rRegion)295 void SdrPaintWindow::HideOverlay(const Region& rRegion)
296 {
297 if(mpOverlayManager && !OutputToPrinter())
298 {
299 if(!mpPreRenderDevice)
300 {
301 mpOverlayManager->restoreBackground(rRegion);
302 }
303 }
304 }
305
GetRedrawRegion() const306 const Region& SdrPaintWindow::GetRedrawRegion() const
307 {
308 return maRedrawRegion;
309 }
310
SetRedrawRegion(const Region & rNew)311 void SdrPaintWindow::SetRedrawRegion(const Region& rNew)
312 {
313 maRedrawRegion = rNew;
314 }
315
316 ////////////////////////////////////////////////////////////////////////////////////////////////////
317 // eof
318