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