1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 #ifndef SD_PRESENTER_PRESENTER_CANVAS_HXX
29 #define SD_PRESENTER_PRESENTER_CANVAS_HXX
30 
31 #include "CanvasUpdateRequester.hxx"
32 #include <basegfx/range/b2drectangle.hxx>
33 #include <com/sun/star/awt/Point.hpp>
34 #include <com/sun/star/awt/XWindow.hpp>
35 #include <com/sun/star/awt/XWindowListener.hpp>
36 #include <com/sun/star/geometry/AffineMatrix2D.hpp>
37 #include <com/sun/star/lang/XInitialization.hpp>
38 #include <com/sun/star/lang/IllegalArgumentException.hpp>
39 #include <com/sun/star/rendering/XSpriteCanvas.hpp>
40 #include <com/sun/star/rendering/VolatileContentDestroyedException.hpp>
41 #include <cppuhelper/basemutex.hxx>
42 #include <cppuhelper/compbase4.hxx>
43 #include <boost/noncopyable.hpp>
44 #include <boost/shared_ptr.hpp>
45 
46 namespace css = ::com::sun::star;
47 
48 namespace sd { namespace presenter {
49 
50 namespace {
51     typedef ::cppu::WeakComponentImplHelper4 <
52         css::rendering::XSpriteCanvas,
53         css::rendering::XBitmap,
54         css::awt::XWindowListener,
55         css::lang::XInitialization
56     > PresenterCanvasInterfaceBase;
57 }
58 
59 /** Wrapper around a shared canvas that forwards most of its methods to the
60     shared canvas.  Most notable differences are:
61     1. The transformation  of the ViewState of forwarded calls is modified by adding
62     an offset.
63     2. The clip polygon of the ViewState of forwarded calls is intersected
64     with a clip rectangle that can be set via SetClip().
65     3. Calls to updateScreen() are collected.  One call to the updateScreen()
66     method of the shared canvas is made asynchronously.
67 
68     The canvas can use different canvases for sharing and for sprite
69     construction.  This allows the shared canvas to be a canvas of sprite itself.
70 */
71 class PresenterCanvas
72     : private ::boost::noncopyable,
73       private ::cppu::BaseMutex,
74       public PresenterCanvasInterfaceBase
75 {
76 public:
77     /** This constructor is used when a PresenterCanvas object is created as
78         a service.
79     */
80     PresenterCanvas (void);
81 
82     /** This constructor is used when a PresenterCanvas object is created
83         directly, typically by the PresenterCanvasFactory.
84         @param rxUpdateCanvas
85             This canvas is used to call updateScreen() at and to create
86             sprites.  In the typical case this canvas is identical to the
87             rxSharedCanvas argument.
88         @param rxUpdateWindow
89             The window that belongs to the canvas given by the
90             rxUpdateCanvas argument.
91         @param rxSharedCanvas
92             The canvas that is wrapped by the new instance of this class.
93             Typically this is a regular XSpriteCanvas and then is identical
94             to the one given by the rxUpdateCanvas argument.  It may be the
95             canvas of a sprite which does not support the XSpriteCanvas
96             interface.  In that case the canvas that created the sprite can
97             be given as rxUpdateCanvas argument to allow to create further
98             sprites and to have proper calls to updateScreen().
99         @param rxSharedWindow
100             The window that belongs to the canvas given by the
101             rxSharedCanvas argument.
102         @param rxWindow
103             The window that is represented by the new PresenterCanvas
104             object.  It is expected to be a direct decendent of
105             rxSharedWindow.  Its position inside rxSharedWindow defines the
106             offset of the canvas implemented by the new PresenterCanvas
107             object and rxSharedCanvas.
108     */
109     PresenterCanvas (
110         const css::uno::Reference<css::rendering::XSpriteCanvas>& rxUpdateCanvas,
111         const css::uno::Reference<css::awt::XWindow>& rxUpdateWindow,
112         const css::uno::Reference<css::rendering::XCanvas>& rxSharedCanvas,
113         const css::uno::Reference<css::awt::XWindow>& rxSharedWindow,
114         const css::uno::Reference<css::awt::XWindow>& rxWindow);
115     virtual ~PresenterCanvas (void);
116 
117     virtual void SAL_CALL disposing (void)
118         throw (css::uno::RuntimeException);
119 
120     css::awt::Point GetOffset (const css::uno::Reference<css::awt::XWindow>& rxBaseWindow);
121 
122     /** Merge the given view state with the view state that translates the
123         (virtual) child canvas to the shared canvas.
124     */
125     css::rendering::ViewState MergeViewState (
126         const css::rendering::ViewState& rViewState,
127         const css::awt::Point& raOffset);
128 
129     css::uno::Reference<css::rendering::XCanvas> GetSharedCanvas (void) const;
130 
131     /** This method is typically called by CanvasPane objects to set the
132         repaint rectangle of a windowPaint() call as clip rectangle.  When
133         no or an empty rectangle is given then the window bounds are used
134         instead.
135         @param rClipRectangle
136             A valid rectangle is used to clip the view state clip polygon.
137             When an empty rectangle is given then the view state clip
138             polygons are clipped against the window bounds.
139     */
140     void SetClip (const css::awt::Rectangle& rClipRectangle);
141 
142     /** Called by custom sprites to update their clip polygon so that they
143         are clipped at the borders of the canvas.  This method has to be
144         called after each change of the sprite location so that the bounds
145         of the canvas can be transformed into the coordinate system of the
146         sprite.
147     */
148     css::uno::Reference<css::rendering::XPolyPolygon2D> UpdateSpriteClip (
149         const css::uno::Reference<css::rendering::XPolyPolygon2D>& rxOriginalClip,
150         const css::geometry::RealPoint2D& rLocation,
151         const css::geometry::RealSize2D& rSize);
152 
153 
154     // XInitialization
155 
156     virtual void SAL_CALL initialize (
157         const css::uno::Sequence<css::uno::Any>& rArguments)
158         throw(css::uno::Exception, css::uno::RuntimeException);
159 
160 
161     // XCanvas
162 
163     virtual void SAL_CALL clear (void)
164         throw (css::uno::RuntimeException);
165 
166     virtual void SAL_CALL drawPoint (
167         const css::geometry::RealPoint2D& aPoint,
168         const css::rendering::ViewState& aViewState,
169         const css::rendering::RenderState& aRenderState)
170         throw (css::lang::IllegalArgumentException, css::uno::RuntimeException);
171 
172     virtual void SAL_CALL drawLine (
173         const css::geometry::RealPoint2D& aStartPoint,
174         const css::geometry::RealPoint2D& aEndPoint,
175         const css::rendering::ViewState& aViewState,
176         const css::rendering::RenderState& aRenderState)
177         throw (css::lang::IllegalArgumentException, css::uno::RuntimeException);
178 
179     virtual void SAL_CALL drawBezier (
180         const css::geometry::RealBezierSegment2D& aBezierSegment,
181         const css::geometry::RealPoint2D& aEndPoint,
182         const css::rendering::ViewState& aViewState,
183         const css::rendering::RenderState& aRenderState)
184         throw (css::lang::IllegalArgumentException, css::uno::RuntimeException);
185 
186     virtual css::uno::Reference<css::rendering::XCachedPrimitive> SAL_CALL drawPolyPolygon (
187         const css::uno::Reference< css::rendering::XPolyPolygon2D >& xPolyPolygon,
188         const css::rendering::ViewState& aViewState,
189         const css::rendering::RenderState& aRenderState)
190         throw (css::lang::IllegalArgumentException, css::uno::RuntimeException);
191 
192     virtual css::uno::Reference<css::rendering::XCachedPrimitive> SAL_CALL strokePolyPolygon (
193         const css::uno::Reference< css::rendering::XPolyPolygon2D >& xPolyPolygon,
194         const css::rendering::ViewState& aViewState,
195         const css::rendering::RenderState& aRenderState,
196         const css::rendering::StrokeAttributes& aStrokeAttributes)
197         throw (css::lang::IllegalArgumentException, css::uno::RuntimeException);
198 
199     virtual css::uno::Reference<css::rendering::XCachedPrimitive> SAL_CALL
200         strokeTexturedPolyPolygon (
201             const css::uno::Reference< css::rendering::XPolyPolygon2D >& xPolyPolygon,
202             const css::rendering::ViewState& aViewState,
203             const css::rendering::RenderState& aRenderState,
204             const css::uno::Sequence< css::rendering::Texture >& aTextures,
205             const css::rendering::StrokeAttributes& aStrokeAttributes)
206         throw (css::lang::IllegalArgumentException,
207             css::rendering::VolatileContentDestroyedException,
208             css::uno::RuntimeException);
209 
210     virtual css::uno::Reference<css::rendering::XCachedPrimitive> SAL_CALL
211         strokeTextureMappedPolyPolygon(
212             const css::uno::Reference<css::rendering::XPolyPolygon2D >& xPolyPolygon,
213             const css::rendering::ViewState& aViewState,
214             const css::rendering::RenderState& aRenderState,
215             const css::uno::Sequence<css::rendering::Texture>& aTextures,
216             const css::uno::Reference<css::geometry::XMapping2D>& xMapping,
217             const css::rendering::StrokeAttributes& aStrokeAttributes)
218         throw (css::lang::IllegalArgumentException,
219             css::rendering::VolatileContentDestroyedException,
220             css::uno::RuntimeException);
221 
222     virtual css::uno::Reference<css::rendering::XPolyPolygon2D> SAL_CALL
223         queryStrokeShapes(
224             const css::uno::Reference<css::rendering::XPolyPolygon2D>& xPolyPolygon,
225             const css::rendering::ViewState& aViewState,
226             const css::rendering::RenderState& aRenderState,
227             const css::rendering::StrokeAttributes& aStrokeAttributes)
228         throw (css::lang::IllegalArgumentException, css::uno::RuntimeException);
229 
230     virtual css::uno::Reference<css::rendering::XCachedPrimitive> SAL_CALL
231         fillPolyPolygon(
232             const css::uno::Reference<css::rendering::XPolyPolygon2D>& xPolyPolygon,
233             const css::rendering::ViewState& aViewState,
234             const css::rendering::RenderState& aRenderState)
235         throw (css::lang::IllegalArgumentException,
236             css::uno::RuntimeException);
237 
238     virtual css::uno::Reference<css::rendering::XCachedPrimitive> SAL_CALL
239         fillTexturedPolyPolygon(
240             const css::uno::Reference<css::rendering::XPolyPolygon2D>& xPolyPolygon,
241             const css::rendering::ViewState& aViewState,
242             const css::rendering::RenderState& aRenderState,
243             const css::uno::Sequence<css::rendering::Texture>& xTextures)
244         throw (css::lang::IllegalArgumentException,
245             css::rendering::VolatileContentDestroyedException,
246             css::uno::RuntimeException);
247 
248     virtual css::uno::Reference<css::rendering::XCachedPrimitive> SAL_CALL
249         fillTextureMappedPolyPolygon(
250             const css::uno::Reference< css::rendering::XPolyPolygon2D >& xPolyPolygon,
251             const css::rendering::ViewState& aViewState,
252             const css::rendering::RenderState& aRenderState,
253             const css::uno::Sequence< css::rendering::Texture >& xTextures,
254             const css::uno::Reference< css::geometry::XMapping2D >& xMapping)
255         throw (css::lang::IllegalArgumentException,
256             css::rendering::VolatileContentDestroyedException,
257             css::uno::RuntimeException);
258 
259     virtual css::uno::Reference<css::rendering::XCanvasFont> SAL_CALL
260         createFont(
261             const css::rendering::FontRequest& aFontRequest,
262             const css::uno::Sequence< css::beans::PropertyValue >& aExtraFontProperties,
263             const css::geometry::Matrix2D& aFontMatrix)
264         throw (css::lang::IllegalArgumentException,
265             css::uno::RuntimeException);
266 
267     virtual css::uno::Sequence<css::rendering::FontInfo> SAL_CALL
268         queryAvailableFonts(
269             const css::rendering::FontInfo& aFilter,
270             const css::uno::Sequence< css::beans::PropertyValue >& aFontProperties)
271         throw (css::lang::IllegalArgumentException, css::uno::RuntimeException);
272 
273     virtual css::uno::Reference<css::rendering::XCachedPrimitive> SAL_CALL
274         drawText(
275             const css::rendering::StringContext& aText,
276             const css::uno::Reference< css::rendering::XCanvasFont >& xFont,
277             const css::rendering::ViewState& aViewState,
278             const css::rendering::RenderState& aRenderState,
279             ::sal_Int8 nTextDirection)
280         throw (css::lang::IllegalArgumentException, css::uno::RuntimeException);
281 
282     virtual css::uno::Reference<css::rendering::XCachedPrimitive> SAL_CALL
283         drawTextLayout(
284             const css::uno::Reference< css::rendering::XTextLayout >& xLayoutetText,
285             const css::rendering::ViewState& aViewState,
286             const css::rendering::RenderState& aRenderState)
287         throw (css::lang::IllegalArgumentException, css::uno::RuntimeException);
288 
289     virtual css::uno::Reference<css::rendering::XCachedPrimitive> SAL_CALL
290         drawBitmap(
291             const css::uno::Reference< css::rendering::XBitmap >& xBitmap,
292             const css::rendering::ViewState& aViewState,
293             const css::rendering::RenderState& aRenderState)
294         throw (css::lang::IllegalArgumentException,
295             css::rendering::VolatileContentDestroyedException,
296             css::uno::RuntimeException);
297 
298     virtual css::uno::Reference<css::rendering::XCachedPrimitive> SAL_CALL
299         drawBitmapModulated(
300             const css::uno::Reference< css::rendering::XBitmap>& xBitmap,
301             const css::rendering::ViewState& aViewState,
302             const css::rendering::RenderState& aRenderState)
303         throw (css::lang::IllegalArgumentException,
304             css::rendering::VolatileContentDestroyedException,
305             css::uno::RuntimeException);
306 
307     virtual css::uno::Reference<css::rendering::XGraphicDevice> SAL_CALL
308         getDevice (void)
309         throw (css::uno::RuntimeException);
310 
311 
312     // XBitmapCanvas
313 
314     void SAL_CALL copyRect(
315         const css::uno::Reference< css::rendering::XBitmapCanvas >& sourceCanvas,
316         const css::geometry::RealRectangle2D& sourceRect,
317         const css::rendering::ViewState& sourceViewState,
318         const css::rendering::RenderState& sourceRenderState,
319         const css::geometry::RealRectangle2D& destRect,
320         const css::rendering::ViewState& destViewState,
321         const css::rendering::RenderState& destRenderState)
322         throw (css::lang::IllegalArgumentException,
323             css::rendering::VolatileContentDestroyedException,
324             css::uno::RuntimeException);
325 
326 
327     // XSpriteCanvas
328 
329     css::uno::Reference< css::rendering::XAnimatedSprite > SAL_CALL
330         createSpriteFromAnimation (
331             const css::uno::Reference< css::rendering::XAnimation >& animation)
332         throw (css::lang::IllegalArgumentException, css::uno::RuntimeException);
333 
334     css::uno::Reference< css::rendering::XAnimatedSprite > SAL_CALL
335         createSpriteFromBitmaps (
336             const css::uno::Sequence<
337                 css::uno::Reference< css::rendering::XBitmap > >& animationBitmaps,
338             ::sal_Int8 interpolationMode)
339         throw (css::lang::IllegalArgumentException,
340             css::rendering::VolatileContentDestroyedException,
341             css::uno::RuntimeException);
342 
343     css::uno::Reference< css::rendering::XCustomSprite > SAL_CALL
344         createCustomSprite (
345             const css::geometry::RealSize2D& spriteSize)
346         throw (css::lang::IllegalArgumentException, css::uno::RuntimeException);
347 
348     css::uno::Reference< css::rendering::XSprite > SAL_CALL
349         createClonedSprite (
350             const css::uno::Reference< css::rendering::XSprite >& original)
351         throw (css::lang::IllegalArgumentException, css::uno::RuntimeException);
352 
353     ::sal_Bool SAL_CALL updateScreen (::sal_Bool bUpdateAll)
354         throw (css::uno::RuntimeException);
355 
356 
357     // XEventListener
358 
359     virtual void SAL_CALL disposing (const css::lang::EventObject& rEvent)
360         throw (css::uno::RuntimeException);
361 
362 
363     // XWindowListener
364 
365     virtual void SAL_CALL windowResized (const css::awt::WindowEvent& rEvent)
366         throw (css::uno::RuntimeException);
367 
368     virtual void SAL_CALL windowMoved (const css::awt::WindowEvent& rEvent)
369         throw (css::uno::RuntimeException);
370 
371     virtual void SAL_CALL windowShown (const css::lang::EventObject& rEvent)
372         throw (css::uno::RuntimeException);
373 
374     virtual void SAL_CALL windowHidden (const css::lang::EventObject& rEvent)
375         throw (css::uno::RuntimeException);
376 
377 
378     // XBitmap
379 
380     virtual css::geometry::IntegerSize2D SAL_CALL getSize (void)
381         throw (css::uno::RuntimeException);
382 
383     virtual sal_Bool SAL_CALL hasAlpha (void)
384         throw (css::uno::RuntimeException);
385 
386     virtual css::uno::Reference<css::rendering::XBitmapCanvas> SAL_CALL queryBitmapCanvas (void)
387         throw (css::uno::RuntimeException);
388 
389     virtual css::uno::Reference<css::rendering::XBitmap> SAL_CALL getScaledBitmap(
390         const css::geometry::RealSize2D& rNewSize,
391         sal_Bool bFast)
392         throw (css::uno::RuntimeException,
393             css::lang::IllegalArgumentException,
394             css::rendering::VolatileContentDestroyedException);
395 
396 private:
397     css::uno::Reference<css::rendering::XSpriteCanvas> mxUpdateCanvas;
398     css::uno::Reference<css::awt::XWindow> mxUpdateWindow;
399     css::uno::Reference<css::rendering::XCanvas> mxSharedCanvas;
400     css::uno::Reference<css::awt::XWindow> mxSharedWindow;
401 
402     /** The window for which a canvas is emulated.
403     */
404     css::uno::Reference<css::awt::XWindow> mxWindow;
405 
406     /** Offset of the emulated canvas with respect to the shared canvas.
407     */
408     css::awt::Point maOffset;
409 
410     /** The UpdateRequester is used by updateScreen() to schedule
411         updateScreen() calls at the shared canvas.
412     */
413     ::boost::shared_ptr<CanvasUpdateRequester> mpUpdateRequester;
414 
415     /** The clip rectangle as given to SetClip().
416     */
417     css::awt::Rectangle maClipRectangle;
418 
419     /** When this flag is true (it is set to true after every call to
420         updateScreen()) then the next call to MergeViewState updates the
421         maOffset member.  A possible optimization would set this flag only
422         to true when one of the windows between mxWindow and mxSharedWindow
423         changes its position.
424     */
425     bool mbOffsetUpdatePending;
426 
427     ::basegfx::B2DRectangle GetClipRectangle (
428         const css::geometry::AffineMatrix2D& rViewTransform,
429         const css::awt::Point& rOffset);
430 
431     css::rendering::ViewState MergeViewState (const css::rendering::ViewState& rViewState);
432 
433     /** This method throws a DisposedException when the object has already been
434         disposed.
435     */
436     void ThrowIfDisposed (void)
437         throw (css::lang::DisposedException);
438 };
439 
440 
441 
442 } } // end of namespace ::sd::presenter
443 
444 #endif
445