1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 #include "precompiled_sd.hxx" 29 30 #include "PresenterCanvas.hxx" 31 32 #include <basegfx/matrix/b2dhommatrix.hxx> 33 #include <basegfx/polygon/b2dpolygontools.hxx> 34 #include <basegfx/polygon/b2dpolypolygon.hxx> 35 #include <basegfx/polygon/b2dpolygonclipper.hxx> 36 #include <basegfx/range/b2drectangle.hxx> 37 #include <basegfx/tools/canvastools.hxx> 38 #include <canvas/canvastools.hxx> 39 #include <cppuhelper/basemutex.hxx> 40 #include <cppuhelper/compbase1.hxx> 41 #include <rtl/ref.hxx> 42 #include <toolkit/helper/vclunohelper.hxx> 43 #include <vcl/window.hxx> 44 #include <vcl/svapp.hxx> 45 46 using namespace ::com::sun::star; 47 using namespace ::com::sun::star::uno; 48 using ::rtl::OUString; 49 50 namespace sd { namespace presenter { 51 52 //===== Service =============================================================== 53 54 Reference<XInterface> SAL_CALL PresenterCanvas_createInstance ( 55 const Reference<XComponentContext>& rxContext) 56 { 57 (void)rxContext; 58 return Reference<XInterface>(static_cast<XWeak*>(new PresenterCanvas())); 59 } 60 61 62 63 64 ::rtl::OUString PresenterCanvas_getImplementationName (void) throw(RuntimeException) 65 { 66 return OUString::createFromAscii("com.sun.star.comp.Draw.PresenterCanvasFactory"); 67 } 68 69 70 71 72 Sequence<rtl::OUString> SAL_CALL PresenterCanvas_getSupportedServiceNames (void) 73 throw (RuntimeException) 74 { 75 static const ::rtl::OUString sServiceName( 76 ::rtl::OUString::createFromAscii("com.sun.star.rendering.Canvas")); 77 return Sequence<rtl::OUString>(&sServiceName, 1); 78 } 79 80 81 82 83 //===== PresenterCustomSprite ================================================= 84 85 /** Wrapper around a sprite that is displayed on a PresenterCanvas. 86 */ 87 namespace { 88 typedef ::cppu::WeakComponentImplHelper1 < 89 css::rendering::XCustomSprite 90 > PresenterCustomSpriteInterfaceBase; 91 } 92 class PresenterCustomSprite 93 : private ::boost::noncopyable, 94 protected ::cppu::BaseMutex, 95 public PresenterCustomSpriteInterfaceBase 96 { 97 public: 98 PresenterCustomSprite ( 99 const rtl::Reference<PresenterCanvas>& rpCanvas, 100 const Reference<rendering::XCustomSprite>& rxSprite, 101 const Reference<awt::XWindow>& rxBaseWindow, 102 const css::geometry::RealSize2D& rSpriteSize); 103 virtual ~PresenterCustomSprite (void); 104 virtual void SAL_CALL disposing (void) 105 throw (RuntimeException); 106 107 // XSprite 108 109 virtual void SAL_CALL setAlpha (double nAlpha) 110 throw (lang::IllegalArgumentException,RuntimeException); 111 112 virtual void SAL_CALL move (const geometry::RealPoint2D& rNewPos, 113 const rendering::ViewState& rViewState, 114 const rendering::RenderState& rRenderState) 115 throw (lang::IllegalArgumentException,RuntimeException); 116 117 virtual void SAL_CALL transform (const geometry::AffineMatrix2D& rTransformation) 118 throw (lang::IllegalArgumentException,RuntimeException); 119 120 virtual void SAL_CALL clip (const Reference<rendering::XPolyPolygon2D>& rClip) 121 throw (RuntimeException); 122 123 virtual void SAL_CALL setPriority (double nPriority) 124 throw (RuntimeException); 125 126 virtual void SAL_CALL show (void) 127 throw (RuntimeException); 128 129 virtual void SAL_CALL hide (void) 130 throw (RuntimeException); 131 132 133 // XCustomSprite 134 135 virtual Reference<rendering::XCanvas> SAL_CALL getContentCanvas (void) 136 throw (RuntimeException); 137 138 private: 139 rtl::Reference<PresenterCanvas> mpCanvas; 140 Reference<rendering::XCustomSprite> mxSprite; 141 Reference<awt::XWindow> mxBaseWindow; 142 geometry::RealPoint2D maPosition; 143 geometry::RealSize2D maSpriteSize; 144 145 void ThrowIfDisposed (void) 146 throw (css::lang::DisposedException); 147 }; 148 149 150 151 152 //===== PresenterCanvas ======================================================= 153 154 155 PresenterCanvas::PresenterCanvas (void) 156 : PresenterCanvasInterfaceBase(m_aMutex), 157 mxUpdateCanvas(), 158 mxSharedCanvas(), 159 mxSharedWindow(), 160 mxWindow(), 161 maOffset(), 162 mpUpdateRequester(), 163 maClipRectangle(), 164 mbOffsetUpdatePending(true) 165 { 166 } 167 168 169 170 171 PresenterCanvas::PresenterCanvas ( 172 const Reference<rendering::XSpriteCanvas>& rxUpdateCanvas, 173 const Reference<awt::XWindow>& rxUpdateWindow, 174 const Reference<rendering::XCanvas>& rxSharedCanvas, 175 const Reference<awt::XWindow>& rxSharedWindow, 176 const Reference<awt::XWindow>& rxWindow) 177 : PresenterCanvasInterfaceBase(m_aMutex), 178 mxUpdateCanvas(rxUpdateCanvas), 179 mxUpdateWindow(rxUpdateWindow), 180 mxSharedCanvas(rxSharedCanvas), 181 mxSharedWindow(rxSharedWindow), 182 mxWindow(rxWindow), 183 maOffset(), 184 mpUpdateRequester(), 185 maClipRectangle(), 186 mbOffsetUpdatePending(true) 187 { 188 if (mxWindow.is()) 189 mxWindow->addWindowListener(this); 190 191 if (mxUpdateCanvas.is()) 192 mpUpdateRequester = CanvasUpdateRequester::Instance(mxUpdateCanvas); 193 } 194 195 196 197 198 PresenterCanvas::~PresenterCanvas (void) 199 { 200 } 201 202 203 204 205 void SAL_CALL PresenterCanvas::disposing (void) 206 throw (css::uno::RuntimeException) 207 { 208 if (mxWindow.is()) 209 mxWindow->removeWindowListener(this); 210 } 211 212 213 214 215 //----- XInitialization ------------------------------------------------------- 216 217 void SAL_CALL PresenterCanvas::initialize ( 218 const Sequence<Any>& rArguments) 219 throw(Exception, RuntimeException) 220 { 221 if (rBHelper.bDisposed || rBHelper.bInDispose) 222 ThrowIfDisposed(); 223 224 if (rArguments.getLength() == 5) 225 { 226 try 227 { 228 // First and second argument may be NULL. 229 rArguments[0] >>= mxUpdateCanvas; 230 rArguments[1] >>= mxUpdateWindow; 231 232 if ( ! (rArguments[2] >>= mxSharedWindow)) 233 { 234 throw lang::IllegalArgumentException( 235 OUString::createFromAscii("PresenterCanvas: invalid shared window"), 236 static_cast<XWeak*>(this), 237 1); 238 } 239 240 if ( ! (rArguments[3] >>= mxSharedCanvas)) 241 { 242 throw lang::IllegalArgumentException( 243 OUString::createFromAscii("PresenterCanvas: invalid shared canvas"), 244 static_cast<XWeak*>(this), 245 2); 246 } 247 248 if ( ! (rArguments[4] >>= mxWindow)) 249 { 250 throw lang::IllegalArgumentException( 251 OUString::createFromAscii("PresenterCanvas: invalid window"), 252 static_cast<XWeak*>(this), 253 3); 254 } 255 256 mpUpdateRequester = CanvasUpdateRequester::Instance(mxUpdateCanvas); 257 258 mbOffsetUpdatePending = true; 259 if (mxWindow.is()) 260 mxWindow->addWindowListener(this); 261 } 262 catch (RuntimeException&) 263 { 264 mxSharedWindow = NULL; 265 mxWindow = NULL; 266 throw; 267 } 268 } 269 else 270 { 271 throw RuntimeException( 272 OUString::createFromAscii("PresenterCanvas: invalid number of arguments"), 273 static_cast<XWeak*>(this)); 274 } 275 } 276 277 278 279 280 //----- XCanvas --------------------------------------------------------------- 281 282 void SAL_CALL PresenterCanvas::clear (void) 283 throw (css::uno::RuntimeException) 284 { 285 ThrowIfDisposed(); 286 // ToDo: Clear the area covered by the child window. A simple forward 287 // would clear the whole shared canvas. 288 } 289 290 291 292 293 void SAL_CALL PresenterCanvas::drawPoint ( 294 const css::geometry::RealPoint2D& aPoint, 295 const css::rendering::ViewState& aViewState, 296 const css::rendering::RenderState& aRenderState) 297 throw (css::lang::IllegalArgumentException, css::uno::RuntimeException) 298 { 299 ThrowIfDisposed(); 300 mxSharedCanvas->drawPoint(aPoint,MergeViewState(aViewState),aRenderState); 301 } 302 303 304 305 306 void SAL_CALL PresenterCanvas::drawLine ( 307 const css::geometry::RealPoint2D& aStartPoint, 308 const css::geometry::RealPoint2D& aEndPoint, 309 const css::rendering::ViewState& aViewState, 310 const css::rendering::RenderState& aRenderState) 311 throw (css::lang::IllegalArgumentException, css::uno::RuntimeException) 312 { 313 ThrowIfDisposed(); 314 mxSharedCanvas->drawLine(aStartPoint,aEndPoint,MergeViewState(aViewState),aRenderState); 315 } 316 317 318 319 320 void SAL_CALL PresenterCanvas::drawBezier ( 321 const css::geometry::RealBezierSegment2D& aBezierSegment, 322 const css::geometry::RealPoint2D& aEndPoint, 323 const css::rendering::ViewState& aViewState, 324 const css::rendering::RenderState& aRenderState) 325 throw (css::lang::IllegalArgumentException, css::uno::RuntimeException) 326 { 327 ThrowIfDisposed(); 328 mxSharedCanvas->drawBezier(aBezierSegment,aEndPoint,MergeViewState(aViewState),aRenderState); 329 } 330 331 332 333 334 css::uno::Reference<css::rendering::XCachedPrimitive> SAL_CALL PresenterCanvas::drawPolyPolygon ( 335 const css::uno::Reference< css::rendering::XPolyPolygon2D >& xPolyPolygon, 336 const css::rendering::ViewState& aViewState, 337 const css::rendering::RenderState& aRenderState) 338 throw (css::lang::IllegalArgumentException, css::uno::RuntimeException) 339 { 340 ThrowIfDisposed(); 341 return mxSharedCanvas->drawPolyPolygon( 342 xPolyPolygon, MergeViewState(aViewState), aRenderState); 343 } 344 345 346 347 348 css::uno::Reference<css::rendering::XCachedPrimitive> SAL_CALL PresenterCanvas::strokePolyPolygon ( 349 const css::uno::Reference< css::rendering::XPolyPolygon2D >& xPolyPolygon, 350 const css::rendering::ViewState& aViewState, 351 const css::rendering::RenderState& aRenderState, 352 const css::rendering::StrokeAttributes& aStrokeAttributes) 353 throw (css::lang::IllegalArgumentException, css::uno::RuntimeException) 354 { 355 ThrowIfDisposed(); 356 return mxSharedCanvas->strokePolyPolygon( 357 xPolyPolygon, MergeViewState(aViewState), aRenderState, aStrokeAttributes); 358 } 359 360 361 362 363 css::uno::Reference<css::rendering::XCachedPrimitive> SAL_CALL 364 PresenterCanvas::strokeTexturedPolyPolygon ( 365 const css::uno::Reference< css::rendering::XPolyPolygon2D >& xPolyPolygon, 366 const css::rendering::ViewState& aViewState, 367 const css::rendering::RenderState& aRenderState, 368 const css::uno::Sequence< css::rendering::Texture >& aTextures, 369 const css::rendering::StrokeAttributes& aStrokeAttributes) 370 throw (css::lang::IllegalArgumentException, 371 css::rendering::VolatileContentDestroyedException, 372 css::uno::RuntimeException) 373 { 374 ThrowIfDisposed(); 375 return mxSharedCanvas->strokeTexturedPolyPolygon( 376 xPolyPolygon, MergeViewState(aViewState), aRenderState, aTextures, aStrokeAttributes); 377 } 378 379 380 381 382 css::uno::Reference<css::rendering::XCachedPrimitive> SAL_CALL 383 PresenterCanvas::strokeTextureMappedPolyPolygon( 384 const css::uno::Reference<css::rendering::XPolyPolygon2D >& xPolyPolygon, 385 const css::rendering::ViewState& aViewState, 386 const css::rendering::RenderState& aRenderState, 387 const css::uno::Sequence<css::rendering::Texture>& aTextures, 388 const css::uno::Reference<css::geometry::XMapping2D>& xMapping, 389 const css::rendering::StrokeAttributes& aStrokeAttributes) 390 throw (css::lang::IllegalArgumentException, 391 css::rendering::VolatileContentDestroyedException, 392 css::uno::RuntimeException) 393 { 394 ThrowIfDisposed(); 395 return mxSharedCanvas->strokeTextureMappedPolyPolygon( 396 xPolyPolygon, 397 MergeViewState(aViewState), 398 aRenderState, 399 aTextures, 400 xMapping, 401 aStrokeAttributes); 402 } 403 404 405 406 407 css::uno::Reference<css::rendering::XPolyPolygon2D> SAL_CALL 408 PresenterCanvas::queryStrokeShapes( 409 const css::uno::Reference<css::rendering::XPolyPolygon2D>& xPolyPolygon, 410 const css::rendering::ViewState& aViewState, 411 const css::rendering::RenderState& aRenderState, 412 const css::rendering::StrokeAttributes& aStrokeAttributes) 413 throw (css::lang::IllegalArgumentException, css::uno::RuntimeException) 414 { 415 ThrowIfDisposed(); 416 return mxSharedCanvas->queryStrokeShapes( 417 xPolyPolygon, MergeViewState(aViewState), aRenderState, aStrokeAttributes); 418 } 419 420 421 422 423 css::uno::Reference<css::rendering::XCachedPrimitive> SAL_CALL 424 PresenterCanvas::fillPolyPolygon( 425 const css::uno::Reference<css::rendering::XPolyPolygon2D>& xPolyPolygon, 426 const css::rendering::ViewState& aViewState, 427 const css::rendering::RenderState& aRenderState) 428 throw (css::lang::IllegalArgumentException, 429 css::uno::RuntimeException) 430 { 431 ThrowIfDisposed(); 432 return mxSharedCanvas->fillPolyPolygon( 433 xPolyPolygon, MergeViewState(aViewState), aRenderState); 434 } 435 436 437 438 439 css::uno::Reference<css::rendering::XCachedPrimitive> SAL_CALL 440 PresenterCanvas::fillTexturedPolyPolygon( 441 const css::uno::Reference<css::rendering::XPolyPolygon2D>& xPolyPolygon, 442 const css::rendering::ViewState& aViewState, 443 const css::rendering::RenderState& aRenderState, 444 const css::uno::Sequence<css::rendering::Texture>& xTextures) 445 throw (css::lang::IllegalArgumentException, 446 css::rendering::VolatileContentDestroyedException, 447 css::uno::RuntimeException) 448 { 449 ThrowIfDisposed(); 450 return mxSharedCanvas->fillTexturedPolyPolygon( 451 xPolyPolygon, MergeViewState(aViewState), aRenderState, xTextures); 452 } 453 454 455 456 457 css::uno::Reference<css::rendering::XCachedPrimitive> SAL_CALL 458 PresenterCanvas::fillTextureMappedPolyPolygon( 459 const css::uno::Reference< css::rendering::XPolyPolygon2D >& xPolyPolygon, 460 const css::rendering::ViewState& aViewState, 461 const css::rendering::RenderState& aRenderState, 462 const css::uno::Sequence< css::rendering::Texture >& xTextures, 463 const css::uno::Reference< css::geometry::XMapping2D >& xMapping) 464 throw (css::lang::IllegalArgumentException, 465 css::rendering::VolatileContentDestroyedException, 466 css::uno::RuntimeException) 467 { 468 ThrowIfDisposed(); 469 return mxSharedCanvas->fillTextureMappedPolyPolygon( 470 xPolyPolygon, MergeViewState(aViewState), aRenderState, xTextures, xMapping); 471 } 472 473 474 475 476 css::uno::Reference<css::rendering::XCanvasFont> SAL_CALL 477 PresenterCanvas::createFont( 478 const css::rendering::FontRequest& aFontRequest, 479 const css::uno::Sequence< css::beans::PropertyValue >& aExtraFontProperties, 480 const css::geometry::Matrix2D& aFontMatrix) 481 throw (css::lang::IllegalArgumentException, 482 css::uno::RuntimeException) 483 { 484 ThrowIfDisposed(); 485 return mxSharedCanvas->createFont( 486 aFontRequest, aExtraFontProperties, aFontMatrix); 487 } 488 489 490 491 492 css::uno::Sequence<css::rendering::FontInfo> SAL_CALL 493 PresenterCanvas::queryAvailableFonts( 494 const css::rendering::FontInfo& aFilter, 495 const css::uno::Sequence< css::beans::PropertyValue >& aFontProperties) 496 throw (css::lang::IllegalArgumentException, css::uno::RuntimeException) 497 { 498 ThrowIfDisposed(); 499 return mxSharedCanvas->queryAvailableFonts(aFilter, aFontProperties); 500 } 501 502 503 504 505 css::uno::Reference<css::rendering::XCachedPrimitive> SAL_CALL 506 PresenterCanvas::drawText( 507 const css::rendering::StringContext& aText, 508 const css::uno::Reference< css::rendering::XCanvasFont >& xFont, 509 const css::rendering::ViewState& aViewState, 510 const css::rendering::RenderState& aRenderState, 511 ::sal_Int8 nTextDirection) 512 throw (css::lang::IllegalArgumentException, css::uno::RuntimeException) 513 { 514 ThrowIfDisposed(); 515 return mxSharedCanvas->drawText( 516 aText, xFont, MergeViewState(aViewState), aRenderState, nTextDirection); 517 } 518 519 520 521 522 css::uno::Reference<css::rendering::XCachedPrimitive> SAL_CALL 523 PresenterCanvas::drawTextLayout( 524 const css::uno::Reference< css::rendering::XTextLayout >& xLayoutetText, 525 const css::rendering::ViewState& aViewState, 526 const css::rendering::RenderState& aRenderState) 527 throw (css::lang::IllegalArgumentException, css::uno::RuntimeException) 528 { 529 ThrowIfDisposed(); 530 return mxSharedCanvas->drawTextLayout( 531 xLayoutetText, MergeViewState(aViewState), aRenderState); 532 } 533 534 535 536 537 css::uno::Reference<css::rendering::XCachedPrimitive> SAL_CALL 538 PresenterCanvas::drawBitmap( 539 const css::uno::Reference< css::rendering::XBitmap >& xBitmap, 540 const css::rendering::ViewState& aViewState, 541 const css::rendering::RenderState& aRenderState) 542 throw (css::lang::IllegalArgumentException, 543 css::rendering::VolatileContentDestroyedException, 544 css::uno::RuntimeException) 545 { 546 ThrowIfDisposed(); 547 return mxSharedCanvas->drawBitmap( 548 xBitmap, MergeViewState(aViewState), aRenderState); 549 } 550 551 552 553 554 css::uno::Reference<css::rendering::XCachedPrimitive> SAL_CALL 555 PresenterCanvas::drawBitmapModulated( 556 const css::uno::Reference< css::rendering::XBitmap>& xBitmap, 557 const css::rendering::ViewState& aViewState, 558 const css::rendering::RenderState& aRenderState) 559 throw (css::lang::IllegalArgumentException, 560 css::rendering::VolatileContentDestroyedException, 561 css::uno::RuntimeException) 562 { 563 ThrowIfDisposed(); 564 return mxSharedCanvas->drawBitmapModulated( 565 xBitmap, MergeViewState(aViewState), aRenderState); 566 } 567 568 569 570 571 css::uno::Reference<css::rendering::XGraphicDevice> SAL_CALL 572 PresenterCanvas::getDevice (void) 573 throw (css::uno::RuntimeException) 574 { 575 ThrowIfDisposed(); 576 return mxSharedCanvas->getDevice(); 577 } 578 579 580 581 582 //----- XBitmapCanvas --------------------------------------------------------- 583 584 void SAL_CALL PresenterCanvas::copyRect( 585 const css::uno::Reference<css::rendering::XBitmapCanvas>& rxSourceCanvas, 586 const css::geometry::RealRectangle2D& rSourceRect, 587 const css::rendering::ViewState& rSourceViewState, 588 const css::rendering::RenderState& rSourceRenderState, 589 const css::geometry::RealRectangle2D& rDestRect, 590 const css::rendering::ViewState& rDestViewState, 591 const css::rendering::RenderState& rDestRenderState) 592 throw (css::lang::IllegalArgumentException, 593 css::rendering::VolatileContentDestroyedException, 594 css::uno::RuntimeException) 595 { 596 ThrowIfDisposed(); 597 598 Reference<rendering::XBitmapCanvas> xBitmapCanvas (mxSharedCanvas, UNO_QUERY); 599 if (xBitmapCanvas.is()) 600 { 601 rendering::ViewState aSourceViewState (rSourceViewState); 602 if (rxSourceCanvas == Reference<rendering::XCanvas>(this)) 603 aSourceViewState = MergeViewState(aSourceViewState); 604 xBitmapCanvas->copyRect( 605 rxSourceCanvas, rSourceRect, aSourceViewState, rSourceRenderState, 606 rDestRect, MergeViewState(rDestViewState), rDestRenderState); 607 } 608 } 609 610 611 612 613 //----- XSpriteCanvas --------------------------------------------------------- 614 615 Reference<rendering::XAnimatedSprite> SAL_CALL 616 PresenterCanvas::createSpriteFromAnimation ( 617 const css::uno::Reference<css::rendering::XAnimation>& rAnimation) 618 throw (css::lang::IllegalArgumentException, css::uno::RuntimeException) 619 { 620 ThrowIfDisposed(); 621 622 Reference<rendering::XSpriteCanvas> xSpriteCanvas (mxSharedCanvas, UNO_QUERY); 623 if (xSpriteCanvas.is()) 624 return xSpriteCanvas->createSpriteFromAnimation(rAnimation); 625 else 626 return NULL; 627 } 628 629 630 631 632 Reference<rendering::XAnimatedSprite> SAL_CALL 633 PresenterCanvas::createSpriteFromBitmaps ( 634 const css::uno::Sequence< 635 css::uno::Reference< css::rendering::XBitmap > >& rAnimationBitmaps, 636 ::sal_Int8 nInterpolationMode) 637 throw (css::lang::IllegalArgumentException, 638 css::rendering::VolatileContentDestroyedException, 639 css::uno::RuntimeException) 640 { 641 ThrowIfDisposed(); 642 643 Reference<rendering::XSpriteCanvas> xSpriteCanvas (mxSharedCanvas, UNO_QUERY); 644 if (xSpriteCanvas.is()) 645 return xSpriteCanvas->createSpriteFromBitmaps(rAnimationBitmaps, nInterpolationMode); 646 else 647 return NULL; 648 } 649 650 651 652 653 Reference<rendering::XCustomSprite> SAL_CALL 654 PresenterCanvas::createCustomSprite ( 655 const css::geometry::RealSize2D& rSpriteSize) 656 throw (css::lang::IllegalArgumentException, css::uno::RuntimeException) 657 { 658 ThrowIfDisposed(); 659 660 Reference<rendering::XSpriteCanvas> xSpriteCanvas (mxSharedCanvas, UNO_QUERY); 661 if (xSpriteCanvas.is()) 662 return new PresenterCustomSprite( 663 this, 664 xSpriteCanvas->createCustomSprite(rSpriteSize), 665 mxSharedWindow, 666 rSpriteSize); 667 else if (mxUpdateCanvas.is()) 668 return new PresenterCustomSprite( 669 this, 670 mxUpdateCanvas->createCustomSprite(rSpriteSize), 671 mxUpdateWindow, 672 rSpriteSize); 673 else 674 return NULL; 675 } 676 677 678 679 680 Reference<rendering::XSprite> SAL_CALL 681 PresenterCanvas::createClonedSprite ( 682 const css::uno::Reference< css::rendering::XSprite >& rxOriginal) 683 throw (css::lang::IllegalArgumentException, css::uno::RuntimeException) 684 { 685 ThrowIfDisposed(); 686 687 Reference<rendering::XSpriteCanvas> xSpriteCanvas (mxSharedCanvas, UNO_QUERY); 688 if (xSpriteCanvas.is()) 689 return xSpriteCanvas->createClonedSprite(rxOriginal); 690 if (mxUpdateCanvas.is()) 691 return mxUpdateCanvas->createClonedSprite(rxOriginal); 692 return NULL; 693 } 694 695 696 697 698 ::sal_Bool SAL_CALL PresenterCanvas::updateScreen (::sal_Bool bUpdateAll) 699 throw (css::uno::RuntimeException) 700 { 701 ThrowIfDisposed(); 702 703 mbOffsetUpdatePending = true; 704 if (mpUpdateRequester.get() != NULL) 705 { 706 mpUpdateRequester->RequestUpdate(bUpdateAll); 707 return sal_True; 708 } 709 else 710 { 711 return sal_False; 712 } 713 } 714 715 716 717 718 //----- XEventListener -------------------------------------------------------- 719 720 void SAL_CALL PresenterCanvas::disposing (const css::lang::EventObject& rEvent) 721 throw (css::uno::RuntimeException) 722 { 723 ThrowIfDisposed(); 724 if (rEvent.Source == mxWindow) 725 mxWindow = NULL; 726 } 727 728 729 730 731 //----- XWindowListener ------------------------------------------------------- 732 733 void SAL_CALL PresenterCanvas::windowResized (const css::awt::WindowEvent& rEvent) 734 throw (css::uno::RuntimeException) 735 { 736 (void)rEvent; 737 ThrowIfDisposed(); 738 mbOffsetUpdatePending = true; 739 } 740 741 742 743 744 void SAL_CALL PresenterCanvas::windowMoved (const css::awt::WindowEvent& rEvent) 745 throw (css::uno::RuntimeException) 746 { 747 (void)rEvent; 748 ThrowIfDisposed(); 749 mbOffsetUpdatePending = true; 750 } 751 752 753 754 755 void SAL_CALL PresenterCanvas::windowShown (const css::lang::EventObject& rEvent) 756 throw (css::uno::RuntimeException) 757 { 758 (void)rEvent; 759 ThrowIfDisposed(); 760 mbOffsetUpdatePending = true; 761 } 762 763 764 765 766 void SAL_CALL PresenterCanvas::windowHidden (const css::lang::EventObject& rEvent) 767 throw (css::uno::RuntimeException) 768 { 769 (void)rEvent; 770 ThrowIfDisposed(); 771 } 772 773 774 775 776 //----- XBitmap --------------------------------------------------------------- 777 778 geometry::IntegerSize2D SAL_CALL PresenterCanvas::getSize (void) 779 throw (RuntimeException) 780 { 781 ThrowIfDisposed(); 782 783 if (mxWindow.is()) 784 { 785 const awt::Rectangle aWindowBox (mxWindow->getPosSize()); 786 return geometry::IntegerSize2D(aWindowBox.Width, aWindowBox.Height); 787 } 788 else 789 return geometry::IntegerSize2D(0,0); 790 } 791 792 793 794 795 sal_Bool SAL_CALL PresenterCanvas::hasAlpha (void) 796 throw (RuntimeException) 797 { 798 Reference<rendering::XBitmap> xBitmap (mxSharedCanvas, UNO_QUERY); 799 if (xBitmap.is()) 800 return xBitmap->hasAlpha(); 801 else 802 return sal_False; 803 } 804 805 806 807 808 Reference<rendering::XBitmapCanvas> SAL_CALL PresenterCanvas::queryBitmapCanvas (void) 809 throw (RuntimeException) 810 { 811 ThrowIfDisposed(); 812 813 return this; 814 } 815 816 817 818 819 Reference<rendering::XBitmap> SAL_CALL PresenterCanvas::getScaledBitmap( 820 const css::geometry::RealSize2D& rNewSize, 821 sal_Bool bFast) 822 throw (css::uno::RuntimeException, 823 css::lang::IllegalArgumentException, 824 css::rendering::VolatileContentDestroyedException) 825 { 826 (void)rNewSize; 827 (void)bFast; 828 829 ThrowIfDisposed(); 830 831 // Not implemented. 832 833 return NULL; 834 } 835 836 837 838 839 //----------------------------------------------------------------------------- 840 841 rendering::ViewState PresenterCanvas::MergeViewState ( 842 const rendering::ViewState& rViewState) 843 { 844 // Make sure the offset is up-to-date. 845 if (mbOffsetUpdatePending) 846 maOffset = GetOffset(mxSharedWindow); 847 return MergeViewState(rViewState, maOffset); 848 } 849 850 851 852 853 css::rendering::ViewState PresenterCanvas::MergeViewState ( 854 const css::rendering::ViewState& rViewState, 855 const css::awt::Point& rOffset) 856 { 857 // Early rejects. 858 if ( ! mxSharedCanvas.is()) 859 return rViewState; 860 861 Reference<rendering::XGraphicDevice> xDevice (mxSharedCanvas->getDevice()); 862 if ( ! xDevice.is()) 863 return rViewState; 864 865 // Create a modifiable copy of the given view state. 866 rendering::ViewState aViewState (rViewState); 867 868 // Prepare the local clip rectangle. 869 ::basegfx::B2DRectangle aWindowRange (GetClipRectangle(aViewState.AffineTransform, rOffset)); 870 871 // Adapt the offset of the view state. 872 aViewState.AffineTransform.m02 += rOffset.X; 873 aViewState.AffineTransform.m12 += rOffset.Y; 874 875 // Adapt the clip polygon. 876 if ( ! aViewState.Clip.is()) 877 { 878 // Cancel out the later multiplication with the view state 879 // transformation. 880 aViewState.Clip = ::basegfx::unotools::xPolyPolygonFromB2DPolyPolygon( 881 xDevice, 882 ::basegfx::B2DPolyPolygon(::basegfx::tools::createPolygonFromRect(aWindowRange))); 883 } 884 else 885 { 886 // Have to compute the intersection of the given clipping polygon in 887 // the view state and the local clip rectangle. 888 889 // Clip the view state clipping polygon against the local clip rectangle. 890 const ::basegfx::B2DPolyPolygon aClipPolygon ( 891 ::basegfx::unotools::b2DPolyPolygonFromXPolyPolygon2D( 892 aViewState.Clip)); 893 const ::basegfx::B2DPolyPolygon aClippedClipPolygon ( 894 ::basegfx::tools::clipPolyPolygonOnRange( 895 aClipPolygon, 896 aWindowRange, 897 true, /* bInside */ 898 false /* bStroke */)); 899 900 aViewState.Clip = ::basegfx::unotools::xPolyPolygonFromB2DPolyPolygon( 901 xDevice, 902 aClippedClipPolygon); 903 } 904 905 return aViewState; 906 } 907 908 909 910 911 awt::Point PresenterCanvas::GetOffset (const Reference<awt::XWindow>& rxBaseWindow) 912 { 913 mbOffsetUpdatePending = false; 914 if (mxWindow.is() && rxBaseWindow.is()) 915 { 916 ::Window* pWindow = VCLUnoHelper::GetWindow(mxWindow); 917 ::Window* pSharedWindow = VCLUnoHelper::GetWindow(rxBaseWindow); 918 if (pWindow!=NULL && pSharedWindow!=NULL) 919 { 920 Rectangle aBox = pWindow->GetWindowExtentsRelative(pSharedWindow); 921 922 // Calculate offset of this canvas with respect to the shared 923 // canvas. 924 return awt::Point(aBox.Left(), aBox.Top()); 925 } 926 } 927 928 return awt::Point(0, 0); 929 } 930 931 932 933 934 ::basegfx::B2DRectangle PresenterCanvas::GetClipRectangle ( 935 const css::geometry::AffineMatrix2D& rViewTransform, 936 const awt::Point& rOffset) 937 { 938 ::basegfx::B2DRectangle aClipRectangle; 939 940 ::Window* pWindow = VCLUnoHelper::GetWindow(mxWindow); 941 if (pWindow == NULL) 942 return ::basegfx::B2DRectangle(); 943 944 ::Window* pSharedWindow = VCLUnoHelper::GetWindow(mxSharedWindow); 945 if (pSharedWindow == NULL) 946 return ::basegfx::B2DRectangle(); 947 948 // Get the bounding box of the window and create a range in the 949 // coordinate system of the child window. 950 Rectangle aLocalClip; 951 if (maClipRectangle.Width <= 0 || maClipRectangle.Height <= 0) 952 { 953 // No clip rectangle has been set via SetClip by the pane. 954 // Use the window extents instead. 955 aLocalClip = pWindow->GetWindowExtentsRelative(pSharedWindow); 956 } 957 else 958 { 959 // Use a previously given clip rectangle. 960 aLocalClip = Rectangle( 961 maClipRectangle.X + rOffset.X, 962 maClipRectangle.Y + rOffset.Y, 963 maClipRectangle.X + maClipRectangle.Width + rOffset.X, 964 maClipRectangle.Y + maClipRectangle.Height + rOffset.Y); 965 } 966 967 // The local clip rectangle is used to clip the view state clipping 968 // polygon. 969 ::basegfx::B2DRectangle aWindowRectangle ( 970 aLocalClip.Left() - rOffset.X, 971 aLocalClip.Top() - rOffset.Y, 972 aLocalClip.Right() - rOffset.X + 1, 973 aLocalClip.Bottom() - rOffset.Y + 1); 974 975 // Calculate the inverted view state transformation to cancel out a 976 // later transformation of the local clip polygon with the view state 977 // transformation. 978 ::basegfx::B2DHomMatrix aInvertedViewStateTransformation; 979 ::basegfx::unotools::homMatrixFromAffineMatrix( 980 aInvertedViewStateTransformation, 981 rViewTransform); 982 if (aInvertedViewStateTransformation.invert()) 983 { 984 // Cancel out the later multiplication with the view state 985 // transformation. 986 aWindowRectangle.transform(aInvertedViewStateTransformation); 987 } 988 989 return aWindowRectangle; 990 } 991 992 993 994 Reference<rendering::XPolyPolygon2D> PresenterCanvas::UpdateSpriteClip ( 995 const Reference<rendering::XPolyPolygon2D>& rxOriginalClip, 996 const geometry::RealPoint2D& rLocation, 997 const geometry::RealSize2D& rSize) 998 { 999 (void)rSize; 1000 1001 // Check used resources and just return the original clip when not 1002 // every one of them is available. 1003 if ( ! mxWindow.is()) 1004 return rxOriginalClip; 1005 1006 Reference<rendering::XGraphicDevice> xDevice (mxSharedCanvas->getDevice()); 1007 if ( ! xDevice.is()) 1008 return rxOriginalClip; 1009 1010 // Determine the bounds of the clip rectangle (the window border) in the 1011 // coordinate system of the sprite. 1012 const awt::Rectangle aWindowBox (mxWindow->getPosSize()); 1013 const double nMinX (-rLocation.X); 1014 const double nMinY (-rLocation.Y); 1015 const double nMaxX (aWindowBox.Width-rLocation.X); 1016 const double nMaxY (aWindowBox.Height-rLocation.Y); 1017 1018 // Create a clip polygon. 1019 Reference<rendering::XPolyPolygon2D> xPolygon; 1020 if (rxOriginalClip.is()) 1021 { 1022 // Combine the original clip with the window clip. 1023 const ::basegfx::B2DPolyPolygon aOriginalClip ( 1024 ::basegfx::unotools::b2DPolyPolygonFromXPolyPolygon2D(rxOriginalClip)); 1025 ::basegfx::B2DRectangle aWindowRange (nMinX, nMinY, nMaxX, nMaxY); 1026 const ::basegfx::B2DPolyPolygon aClippedClipPolygon ( 1027 ::basegfx::tools::clipPolyPolygonOnRange( 1028 aOriginalClip, 1029 aWindowRange, 1030 true, /* bInside */ 1031 false /* bStroke */)); 1032 xPolygon = ::basegfx::unotools::xPolyPolygonFromB2DPolyPolygon( 1033 xDevice, 1034 aClippedClipPolygon); 1035 } 1036 else 1037 { 1038 // Create a new clip polygon from the window clip rectangle. 1039 Sequence<Sequence<geometry::RealPoint2D> > aPoints (1); 1040 aPoints[0] = Sequence<geometry::RealPoint2D>(4); 1041 aPoints[0][0] = geometry::RealPoint2D(nMinX,nMinY); 1042 aPoints[0][1] = geometry::RealPoint2D(nMaxX,nMinY); 1043 aPoints[0][2] = geometry::RealPoint2D(nMaxX,nMaxY); 1044 aPoints[0][3] = geometry::RealPoint2D(nMinX,nMaxY); 1045 Reference<rendering::XLinePolyPolygon2D> xLinePolygon( 1046 xDevice->createCompatibleLinePolyPolygon(aPoints)); 1047 if (xLinePolygon.is()) 1048 xLinePolygon->setClosed(0, sal_True); 1049 xPolygon = Reference<rendering::XPolyPolygon2D>(xLinePolygon, UNO_QUERY); 1050 } 1051 1052 return xPolygon; 1053 } 1054 1055 1056 1057 1058 void PresenterCanvas::ThrowIfDisposed (void) 1059 throw (css::lang::DisposedException) 1060 { 1061 if (rBHelper.bDisposed || rBHelper.bInDispose || ! mxSharedCanvas.is()) 1062 { 1063 throw lang::DisposedException ( 1064 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( 1065 "PresenterCanvas object has already been disposed")), 1066 static_cast<uno::XWeak*>(this)); 1067 } 1068 } 1069 1070 1071 1072 1073 //===== PresenterCustomSprite ================================================= 1074 1075 1076 PresenterCustomSprite::PresenterCustomSprite ( 1077 const rtl::Reference<PresenterCanvas>& rpCanvas, 1078 const Reference<rendering::XCustomSprite>& rxSprite, 1079 const Reference<awt::XWindow>& rxBaseWindow, 1080 const css::geometry::RealSize2D& rSpriteSize) 1081 : PresenterCustomSpriteInterfaceBase(m_aMutex), 1082 mpCanvas(rpCanvas), 1083 mxSprite(rxSprite), 1084 mxBaseWindow(rxBaseWindow), 1085 maPosition(0,0), 1086 maSpriteSize(rSpriteSize) 1087 { 1088 } 1089 1090 1091 1092 1093 PresenterCustomSprite::~PresenterCustomSprite (void) 1094 { 1095 } 1096 1097 1098 1099 1100 void SAL_CALL PresenterCustomSprite::disposing (void) 1101 throw (RuntimeException) 1102 { 1103 Reference<XComponent> xComponent (mxSprite, UNO_QUERY); 1104 mxSprite = NULL; 1105 if (xComponent.is()) 1106 xComponent->dispose(); 1107 mpCanvas = rtl::Reference<PresenterCanvas>(); 1108 } 1109 1110 1111 1112 1113 //----- XSprite --------------------------------------------------------------- 1114 1115 void SAL_CALL PresenterCustomSprite::setAlpha (const double nAlpha) 1116 throw (lang::IllegalArgumentException,RuntimeException) 1117 { 1118 ThrowIfDisposed(); 1119 mxSprite->setAlpha(nAlpha); 1120 } 1121 1122 1123 1124 1125 void SAL_CALL PresenterCustomSprite::move ( 1126 const geometry::RealPoint2D& rNewPos, 1127 const rendering::ViewState& rViewState, 1128 const rendering::RenderState& rRenderState) 1129 throw (lang::IllegalArgumentException,RuntimeException) 1130 { 1131 ThrowIfDisposed(); 1132 maPosition = rNewPos; 1133 mxSprite->move( 1134 rNewPos, 1135 mpCanvas->MergeViewState(rViewState, mpCanvas->GetOffset(mxBaseWindow)), 1136 rRenderState); 1137 // Clip sprite against window bounds. This call is necessary because 1138 // sprite clipping is done in the corrdinate system of the sprite. 1139 // Therefore, after each change of the sprites location the window 1140 // bounds have to be transformed into the sprites coordinate system. 1141 clip(NULL); 1142 } 1143 1144 1145 1146 1147 void SAL_CALL PresenterCustomSprite::transform (const geometry::AffineMatrix2D& rTransformation) 1148 throw (lang::IllegalArgumentException,RuntimeException) 1149 { 1150 ThrowIfDisposed(); 1151 mxSprite->transform(rTransformation); 1152 } 1153 1154 1155 1156 1157 void SAL_CALL PresenterCustomSprite::clip (const Reference<rendering::XPolyPolygon2D>& rxClip) 1158 throw (RuntimeException) 1159 { 1160 ThrowIfDisposed(); 1161 // The clip region is expected in the coordinate system of the sprite. 1162 // UpdateSpriteClip() integrates the window bounds, transformed into the 1163 // sprites coordinate system, with the given clip. 1164 mxSprite->clip(mpCanvas->UpdateSpriteClip(rxClip, maPosition, maSpriteSize)); 1165 } 1166 1167 1168 1169 1170 void SAL_CALL PresenterCustomSprite::setPriority (const double nPriority) 1171 throw (RuntimeException) 1172 { 1173 ThrowIfDisposed(); 1174 mxSprite->setPriority(nPriority); 1175 } 1176 1177 1178 1179 void SAL_CALL PresenterCustomSprite::show (void) 1180 throw (RuntimeException) 1181 { 1182 ThrowIfDisposed(); 1183 mxSprite->show(); 1184 } 1185 1186 1187 1188 1189 void SAL_CALL PresenterCustomSprite::hide (void) 1190 throw (RuntimeException) 1191 { 1192 ThrowIfDisposed(); 1193 mxSprite->hide(); 1194 } 1195 1196 1197 1198 1199 //----- XCustomSprite --------------------------------------------------------- 1200 1201 Reference<rendering::XCanvas> PresenterCustomSprite::getContentCanvas (void) 1202 throw (RuntimeException) 1203 { 1204 ThrowIfDisposed(); 1205 return mxSprite->getContentCanvas(); 1206 } 1207 1208 1209 1210 1211 //----------------------------------------------------------------------------- 1212 1213 void PresenterCustomSprite::ThrowIfDisposed (void) 1214 throw (css::lang::DisposedException) 1215 { 1216 if (rBHelper.bDisposed || rBHelper.bInDispose || ! mxSprite.is()) 1217 { 1218 throw lang::DisposedException ( 1219 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( 1220 "PresenterCustomSprite object has already been disposed")), 1221 static_cast<uno::XWeak*>(this)); 1222 } 1223 } 1224 1225 1226 1227 1228 } } // end of namespace ::sd::presenter 1229