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