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