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