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/sdr/contact/objectcontactofpageview.hxx> 27 #include <svx/sdr/contact/viewobjectcontactofunocontrol.hxx> 28 #include <svx/svdpagv.hxx> 29 #include <svx/svdpage.hxx> 30 #include <svx/sdr/contact/displayinfo.hxx> 31 #include <svx/sdr/contact/viewobjectcontact.hxx> 32 #include <svx/svdview.hxx> 33 #include <svx/sdr/contact/viewcontact.hxx> 34 #include <svx/sdr/animation/objectanimator.hxx> 35 #include <svx/sdr/event/eventhandler.hxx> 36 #include <svx/sdrpagewindow.hxx> 37 #include <svx/sdrpaintwindow.hxx> 38 #include <basegfx/matrix/b2dhommatrix.hxx> 39 #include <drawinglayer/primitive2d/transformprimitive2d.hxx> 40 #include <com/sun/star/rendering/XSpriteCanvas.hpp> 41 #include <drawinglayer/processor2d/processor2dtools.hxx> 42 #include <svx/unoapi.hxx> 43 44 ////////////////////////////////////////////////////////////////////////////// 45 46 using namespace com::sun::star; 47 48 ////////////////////////////////////////////////////////////////////////////// 49 50 namespace sdr 51 { 52 namespace contact 53 { 54 // internal access to SdrPage of SdrPageView GetSdrPage() const55 SdrPage* ObjectContactOfPageView::GetSdrPage() const 56 { 57 return GetPageWindow().GetPageView().GetPage(); 58 } 59 ObjectContactOfPageView(SdrPageWindow & rPageWindow)60 ObjectContactOfPageView::ObjectContactOfPageView(SdrPageWindow& rPageWindow) 61 : ObjectContact(), 62 mrPageWindow(rPageWindow) 63 { 64 // init PreviewRenderer flag 65 setPreviewRenderer(((SdrPaintView&)rPageWindow.GetPageView().GetView()).IsPreviewRenderer()); 66 67 // init timer 68 SetTimeout(1); 69 Stop(); 70 } 71 ~ObjectContactOfPageView()72 ObjectContactOfPageView::~ObjectContactOfPageView() 73 { 74 // execute missing LazyInvalidates and stop timer 75 Timeout(); 76 } 77 78 // LazyInvalidate request. Take action. setLazyInvalidate(ViewObjectContact &)79 void ObjectContactOfPageView::setLazyInvalidate(ViewObjectContact& /*rVOC*/) 80 { 81 // do NOT call parent, but remember that something is to do by 82 // starting the LazyInvalidateTimer 83 Start(); 84 } 85 86 // call this to support evtl. preparations for repaint PrepareProcessDisplay()87 void ObjectContactOfPageView::PrepareProcessDisplay() 88 { 89 if(IsActive()) 90 { 91 static bool bInvalidateDuringPaint(true); 92 93 if(bInvalidateDuringPaint) 94 { 95 // there are still non-triggered LazyInvalidate events, trigger these 96 Timeout(); 97 } 98 } 99 } 100 101 // From baseclass Timer, the timeout call triggered by te LazyInvalidate mechanism Timeout()102 void ObjectContactOfPageView::Timeout() 103 { 104 // stop the timer 105 Stop(); 106 107 // invalidate all LazyInvalidate VOCs new situations 108 const sal_uInt32 nVOCCount(getViewObjectContactCount()); 109 110 for(sal_uInt32 a(0); a < nVOCCount; a++) 111 { 112 ViewObjectContact* pCandidate = getViewObjectContact(a); 113 pCandidate->triggerLazyInvalidate(); 114 } 115 } 116 117 // Process the whole displaying ProcessDisplay(DisplayInfo & rDisplayInfo)118 void ObjectContactOfPageView::ProcessDisplay(DisplayInfo& rDisplayInfo) 119 { 120 const SdrPage* pStartPage = GetSdrPage(); 121 122 if(pStartPage && !rDisplayInfo.GetProcessLayers().IsEmpty()) 123 { 124 const ViewContact& rDrawPageVC = pStartPage->GetViewContact(); 125 126 if(rDrawPageVC.GetObjectCount()) 127 { 128 DoProcessDisplay(rDisplayInfo); 129 } 130 } 131 132 // after paint take care of the evtl. scheduled asynchronious commands. 133 // Do this by resetting the timer contained there. Thus, after the paint 134 // that timer will be triggered and the events will be executed. 135 if(HasEventHandler()) 136 { 137 sdr::event::TimerEventHandler& rEventHandler = GetEventHandler(); 138 139 if(!rEventHandler.IsEmpty()) 140 { 141 rEventHandler.Restart(); 142 } 143 } 144 } 145 146 // Process the whole displaying. Only use given DsiplayInfo, do not access other 147 // OutputDevices then the given ones. DoProcessDisplay(DisplayInfo & rDisplayInfo)148 void ObjectContactOfPageView::DoProcessDisplay(DisplayInfo& rDisplayInfo) 149 { 150 // visualize entered group when that feature is switched on and it's not 151 // a print output. #i29129# No ghosted display for printing. 152 sal_Bool bVisualizeEnteredGroup(DoVisualizeEnteredGroup() && !isOutputToPrinter()); 153 154 // Visualize entered groups: Set to ghosted as default 155 // start. Do this only for the DrawPage, not for MasterPages 156 if(bVisualizeEnteredGroup) 157 { 158 rDisplayInfo.SetGhostedDrawMode(); 159 } 160 161 // #114359# save old and set clip region 162 OutputDevice* pOutDev = TryToGetOutputDevice(); 163 OSL_ENSURE(0 != pOutDev, "ObjectContactOfPageView without OutDev, someone has overloaded TryToGetOutputDevice wrong (!)"); 164 sal_Bool bClipRegionPushed(sal_False); 165 const Region& rRedrawArea(rDisplayInfo.GetRedrawArea()); 166 167 if(!rRedrawArea.IsEmpty()) 168 { 169 bClipRegionPushed = sal_True; 170 pOutDev->Push(PUSH_CLIPREGION); 171 pOutDev->IntersectClipRegion(rRedrawArea); 172 } 173 174 // Get start node and process DrawPage contents 175 const ViewObjectContact& rDrawPageVOContact = GetSdrPage()->GetViewContact().GetViewObjectContact(*this); 176 177 // update current ViewInformation2D at the ObjectContact 178 const double fCurrentTime(getPrimitiveAnimator().GetTime()); 179 OutputDevice& rTargetOutDev = GetPageWindow().GetPaintWindow().GetTargetOutputDevice(); 180 basegfx::B2DRange aViewRange; 181 182 // create ViewRange 183 if(isOutputToRecordingMetaFile()) 184 { 185 if(isOutputToPDFFile() || isOutputToPrinter()) 186 { 187 // #i98402# if it's a PDF export, set the ClipRegion as ViewRange. This is 188 // mainly because SW does not use DrawingLayer Page-Oriented and if not doing this, 189 // all existing objects will be collected as primitives and processed. 190 // OD 2009-03-05 #i99876# perform the same also for SW on printing. 191 const Rectangle aLogicClipRectangle(rDisplayInfo.GetRedrawArea().GetBoundRect()); 192 193 aViewRange = basegfx::B2DRange( 194 aLogicClipRectangle.Left(), aLogicClipRectangle.Top(), 195 aLogicClipRectangle.Right(), aLogicClipRectangle.Bottom()); 196 } 197 } 198 else 199 { 200 // use visible pixels, but transform to world coordinates 201 const Size aOutputSizePixel(rTargetOutDev.GetOutputSizePixel()); 202 aViewRange = basegfx::B2DRange(0.0, 0.0, aOutputSizePixel.getWidth(), aOutputSizePixel.getHeight()); 203 204 // if a clip region is set, use it 205 if(!rDisplayInfo.GetRedrawArea().IsEmpty()) 206 { 207 // get logic clip range and create discrete one 208 const Rectangle aLogicClipRectangle(rDisplayInfo.GetRedrawArea().GetBoundRect()); 209 basegfx::B2DRange aLogicClipRange( 210 aLogicClipRectangle.Left(), aLogicClipRectangle.Top(), 211 aLogicClipRectangle.Right(), aLogicClipRectangle.Bottom()); 212 basegfx::B2DRange aDiscreteClipRange(aLogicClipRange); 213 aDiscreteClipRange.transform(rTargetOutDev.GetViewTransformation()); 214 215 // align the discrete one to discrete boundaries (pixel bounds). Also 216 // expand X and Y max by one due to Rectangle definition source 217 aDiscreteClipRange.expand(basegfx::B2DTuple( 218 floor(aDiscreteClipRange.getMinX()), 219 floor(aDiscreteClipRange.getMinY()))); 220 aDiscreteClipRange.expand(basegfx::B2DTuple( 221 1.0 + ceil(aDiscreteClipRange.getMaxX()), 222 1.0 + ceil(aDiscreteClipRange.getMaxY()))); 223 224 // intersect current ViewRange with ClipRange 225 aViewRange.intersect(aDiscreteClipRange); 226 } 227 228 // transform to world coordinates 229 aViewRange.transform(rTargetOutDev.GetInverseViewTransformation()); 230 } 231 232 // update local ViewInformation2D 233 const drawinglayer::geometry::ViewInformation2D aNewViewInformation2D( 234 basegfx::B2DHomMatrix(), 235 rTargetOutDev.GetViewTransformation(), 236 aViewRange, 237 GetXDrawPageForSdrPage(GetSdrPage()), 238 fCurrentTime, 239 uno::Sequence<beans::PropertyValue>()); 240 updateViewInformation2D(aNewViewInformation2D); 241 242 // get whole Primitive2DSequence; this will already make use of updated ViewInformation2D 243 // and may use the MapMode from the Target OutDev in the DisplayInfo 244 drawinglayer::primitive2d::Primitive2DSequence xPrimitiveSequence(rDrawPageVOContact.getPrimitive2DSequenceHierarchy(rDisplayInfo)); 245 246 // if there is something to show, use a primitive processor to render it. There 247 // is a choice between VCL and Canvas processors currently. The decision is made in 248 // createProcessor2DFromOutputDevice and takes into accout things like the 249 // Target is a MetaFile, a VDev or something else. The Canvas renderer is triggered 250 // currently using the shown boolean. Canvas is not yet the default. 251 if(xPrimitiveSequence.hasElements()) 252 { 253 // prepare OutputDevice (historical stuff, maybe soon removed) 254 rDisplayInfo.ClearGhostedDrawMode(); // reset, else the VCL-paint with the processor will not do the right thing 255 pOutDev->SetLayoutMode(0); // reset, default is no BiDi/RTL 256 257 // create renderer 258 drawinglayer::processor2d::BaseProcessor2D* pProcessor2D = drawinglayer::processor2d::createProcessor2DFromOutputDevice( 259 rTargetOutDev, 260 getViewInformation2D()); 261 262 if(pProcessor2D) 263 { 264 pProcessor2D->process(xPrimitiveSequence); 265 delete pProcessor2D; 266 } 267 } 268 269 // #114359# restore old ClipReghion 270 if(bClipRegionPushed) 271 { 272 pOutDev->Pop(); 273 } 274 275 // Visualize entered groups: Reset to original DrawMode 276 if(bVisualizeEnteredGroup) 277 { 278 rDisplayInfo.ClearGhostedDrawMode(); 279 } 280 } 281 282 // test if visualizing of entered groups is switched on at all DoVisualizeEnteredGroup() const283 bool ObjectContactOfPageView::DoVisualizeEnteredGroup() const 284 { 285 SdrView& rView = GetPageWindow().GetPageView().GetView(); 286 return rView.DoVisualizeEnteredGroup(); 287 } 288 289 // get active group's (the entered group) ViewContact getActiveViewContact() const290 const ViewContact* ObjectContactOfPageView::getActiveViewContact() const 291 { 292 SdrObjList* pActiveGroupList = GetPageWindow().GetPageView().GetObjList(); 293 294 if(pActiveGroupList) 295 { 296 if(pActiveGroupList->ISA(SdrPage)) 297 { 298 // It's a Page itself 299 return &(((SdrPage*)pActiveGroupList)->GetViewContact()); 300 } 301 else if(pActiveGroupList->GetOwnerObj()) 302 { 303 // Group object 304 return &(pActiveGroupList->GetOwnerObj()->GetViewContact()); 305 } 306 } 307 else if(GetSdrPage()) 308 { 309 // use page of associated SdrPageView 310 return &(GetSdrPage()->GetViewContact()); 311 } 312 313 return 0; 314 } 315 316 // Invalidate given rectangle at the window/output which is represented by 317 // this ObjectContact. InvalidatePartOfView(const basegfx::B2DRange & rRange) const318 void ObjectContactOfPageView::InvalidatePartOfView(const basegfx::B2DRange& rRange) const 319 { 320 // invalidate at associated PageWindow 321 GetPageWindow().InvalidatePageWindow(rRange); 322 } 323 324 // Get info if given Rectangle is visible in this view IsAreaVisible(const basegfx::B2DRange & rRange) const325 bool ObjectContactOfPageView::IsAreaVisible(const basegfx::B2DRange& rRange) const 326 { 327 // compare with the visible rectangle 328 if(rRange.isEmpty()) 329 { 330 // no range -> not visible 331 return false; 332 } 333 else 334 { 335 const OutputDevice& rTargetOutDev = GetPageWindow().GetPaintWindow().GetTargetOutputDevice(); 336 const Size aOutputSizePixel(rTargetOutDev.GetOutputSizePixel()); 337 basegfx::B2DRange aLogicViewRange(0.0, 0.0, aOutputSizePixel.getWidth(), aOutputSizePixel.getHeight()); 338 339 aLogicViewRange.transform(rTargetOutDev.GetInverseViewTransformation()); 340 341 if(!aLogicViewRange.isEmpty() && !aLogicViewRange.overlaps(rRange)) 342 { 343 return false; 344 } 345 } 346 347 // call parent 348 return ObjectContact::IsAreaVisible(rRange); 349 } 350 351 // Get info about the need to visualize GluePoints AreGluePointsVisible() const352 bool ObjectContactOfPageView::AreGluePointsVisible() const 353 { 354 return GetPageWindow().GetPageView().GetView().ImpIsGlueVisible(); 355 } 356 357 // check if text animation is allowed. IsTextAnimationAllowed() const358 bool ObjectContactOfPageView::IsTextAnimationAllowed() const 359 { 360 SdrView& rView = GetPageWindow().GetPageView().GetView(); 361 const SvtAccessibilityOptions& rOpt = rView.getAccessibilityOptions(); 362 return rOpt.GetIsAllowAnimatedText(); 363 } 364 365 // check if graphic animation is allowed. IsGraphicAnimationAllowed() const366 bool ObjectContactOfPageView::IsGraphicAnimationAllowed() const 367 { 368 SdrView& rView = GetPageWindow().GetPageView().GetView(); 369 const SvtAccessibilityOptions& rOpt = rView.getAccessibilityOptions(); 370 return rOpt.GetIsAllowAnimatedGraphics(); 371 } 372 373 // check if asynchronious graphis loading is allowed. Default is sal_False. IsAsynchronGraphicsLoadingAllowed() const374 bool ObjectContactOfPageView::IsAsynchronGraphicsLoadingAllowed() const 375 { 376 SdrView& rView = GetPageWindow().GetPageView().GetView(); 377 return rView.IsSwapAsynchron(); 378 } 379 380 // check if buffering of MasterPages is allowed. Default is sal_False. IsMasterPageBufferingAllowed() const381 bool ObjectContactOfPageView::IsMasterPageBufferingAllowed() const 382 { 383 SdrView& rView = GetPageWindow().GetPageView().GetView(); 384 return rView.IsMasterPagePaintCaching(); 385 } 386 387 // print? isOutputToPrinter() const388 bool ObjectContactOfPageView::isOutputToPrinter() const 389 { 390 return (OUTDEV_PRINTER == mrPageWindow.GetPaintWindow().GetOutputDevice().GetOutDevType()); 391 } 392 393 // window? isOutputToWindow() const394 bool ObjectContactOfPageView::isOutputToWindow() const 395 { 396 return (OUTDEV_WINDOW == mrPageWindow.GetPaintWindow().GetOutputDevice().GetOutDevType()); 397 } 398 399 // VirtualDevice? isOutputToVirtualDevice() const400 bool ObjectContactOfPageView::isOutputToVirtualDevice() const 401 { 402 return (OUTDEV_VIRDEV == mrPageWindow.GetPaintWindow().GetOutputDevice().GetOutDevType()); 403 } 404 405 // recording MetaFile? isOutputToRecordingMetaFile() const406 bool ObjectContactOfPageView::isOutputToRecordingMetaFile() const 407 { 408 GDIMetaFile* pMetaFile = mrPageWindow.GetPaintWindow().GetOutputDevice().GetConnectMetaFile(); 409 return (pMetaFile && pMetaFile->IsRecord() && !pMetaFile->IsPause()); 410 } 411 412 // pdf export? isOutputToPDFFile() const413 bool ObjectContactOfPageView::isOutputToPDFFile() const 414 { 415 return (0 != mrPageWindow.GetPaintWindow().GetOutputDevice().GetPDFWriter()); 416 } 417 418 // gray display mode isDrawModeGray() const419 bool ObjectContactOfPageView::isDrawModeGray() const 420 { 421 const sal_uInt32 nDrawMode(mrPageWindow.GetPaintWindow().GetOutputDevice().GetDrawMode()); 422 return (nDrawMode == (DRAWMODE_GRAYLINE|DRAWMODE_GRAYFILL|DRAWMODE_BLACKTEXT|DRAWMODE_GRAYBITMAP|DRAWMODE_GRAYGRADIENT)); 423 } 424 425 // gray display mode isDrawModeBlackWhite() const426 bool ObjectContactOfPageView::isDrawModeBlackWhite() const 427 { 428 const sal_uInt32 nDrawMode(mrPageWindow.GetPaintWindow().GetOutputDevice().GetDrawMode()); 429 return (nDrawMode == (DRAWMODE_BLACKLINE|DRAWMODE_BLACKTEXT|DRAWMODE_WHITEFILL|DRAWMODE_GRAYBITMAP|DRAWMODE_WHITEGRADIENT)); 430 } 431 432 // high contrast display mode isDrawModeHighContrast() const433 bool ObjectContactOfPageView::isDrawModeHighContrast() const 434 { 435 const sal_uInt32 nDrawMode(mrPageWindow.GetPaintWindow().GetOutputDevice().GetDrawMode()); 436 return (nDrawMode == (DRAWMODE_SETTINGSLINE|DRAWMODE_SETTINGSFILL|DRAWMODE_SETTINGSTEXT|DRAWMODE_SETTINGSGRADIENT)); 437 } 438 439 // access to SdrPageView TryToGetSdrPageView() const440 SdrPageView* ObjectContactOfPageView::TryToGetSdrPageView() const 441 { 442 return &(mrPageWindow.GetPageView()); 443 } 444 445 446 // access to OutputDevice TryToGetOutputDevice() const447 OutputDevice* ObjectContactOfPageView::TryToGetOutputDevice() const 448 { 449 SdrPreRenderDevice* pPreRenderDevice = mrPageWindow.GetPaintWindow().GetPreRenderDevice(); 450 451 if(pPreRenderDevice) 452 { 453 return &(pPreRenderDevice->GetPreRenderDevice()); 454 } 455 else 456 { 457 return &(mrPageWindow.GetPaintWindow().GetOutputDevice()); 458 } 459 } 460 461 // set all UNO controls displayed in the view to design/alive mode SetUNOControlsDesignMode(bool _bDesignMode) const462 void ObjectContactOfPageView::SetUNOControlsDesignMode( bool _bDesignMode ) const 463 { 464 const sal_uInt32 nCount(getViewObjectContactCount()); 465 466 for(sal_uInt32 a(0); a < nCount; a++) 467 { 468 const ViewObjectContact* pVOC = getViewObjectContact(a); 469 const ViewObjectContactOfUnoControl* pUnoObjectVOC = dynamic_cast< const ViewObjectContactOfUnoControl* >(pVOC); 470 471 if(pUnoObjectVOC) 472 { 473 pUnoObjectVOC->setControlDesignMode(_bDesignMode); 474 } 475 } 476 } 477 } // end of namespace contact 478 } // end of namespace sdr 479 480 ////////////////////////////////////////////////////////////////////////////// 481 // eof 482