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