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 
SdrPreRenderDevice(OutputDevice & rOriginal)33 SdrPreRenderDevice::SdrPreRenderDevice(OutputDevice& rOriginal)
34 :	mrOutputDevice(rOriginal)
35 {
36 }
37 
~SdrPreRenderDevice()38 SdrPreRenderDevice::~SdrPreRenderDevice()
39 {
40 }
41 
PreparePreRenderDevice()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 
OutputPreRenderDevice(const Region & rExpandedRegion)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 
impCreateOverlayManager()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 
SdrPaintWindow(SdrPaintView & rNewPaintView,OutputDevice & rOut)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 
~SdrPaintWindow()196 SdrPaintWindow::~SdrPaintWindow()
197 {
198 	if(mpOverlayManager)
199 	{
200 		delete mpOverlayManager;
201 		mpOverlayManager = 0L;
202 	}
203 
204 	DestroyPreRenderDevice();
205 }
206 
GetOverlayManager() const207 ::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 
GetVisibleArea() const218 Rectangle SdrPaintWindow::GetVisibleArea() const
219 {
220 	Size aVisSizePixel(GetOutputDevice().GetOutputSizePixel());
221 	return Rectangle(GetOutputDevice().PixelToLogic(Rectangle(Point(0,0), aVisSizePixel)));
222 }
223 
OutputToRecordingMetaFile() const224 sal_Bool SdrPaintWindow::OutputToRecordingMetaFile() const
225 {
226 	GDIMetaFile* pMetaFile = mrOutputDevice.GetConnectMetaFile();
227 	return (pMetaFile && pMetaFile->IsRecord() && !pMetaFile->IsPause());
228 }
229 
PreparePreRenderDevice()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 
DestroyPreRenderDevice()256 void SdrPaintWindow::DestroyPreRenderDevice()
257 {
258 	if(mpPreRenderDevice)
259 	{
260 		delete mpPreRenderDevice;
261 		mpPreRenderDevice = 0L;
262 	}
263 }
264 
OutputPreRenderDevice(const Region & rExpandedRegion)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
DrawOverlay(const Region & rRegion)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 
HideOverlay(const Region & rRegion)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 
GetRedrawRegion() const304 const Region& SdrPaintWindow::GetRedrawRegion() const
305 {
306 	return maRedrawRegion;
307 }
308 
SetRedrawRegion(const Region & rNew)309 void SdrPaintWindow::SetRedrawRegion(const Region& rNew)
310 {
311 	maRedrawRegion = rNew;
312 }
313 
314 /* vim: set noet sw=4 ts=4: */
315