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