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