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