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 : // must be first
22 : #include <canvas/debug.hxx>
23 :
24 : #include <com/sun/star/awt/Rectangle.hpp>
25 : #include <com/sun/star/beans/XPropertySet.hpp>
26 : #include <com/sun/star/awt/FontWeight.hpp>
27 :
28 : #include <vcl/metaact.hxx>
29 : #include <vcl/gdimtf.hxx>
30 :
31 : #include <basegfx/numeric/ftools.hxx>
32 :
33 : #include <boost/bind.hpp>
34 :
35 : #include <cmath>
36 : #include <algorithm>
37 : #include <functional>
38 : #include <limits>
39 :
40 : #include "backgroundshape.hxx"
41 : #include "slideshowexceptions.hxx"
42 : #include "slideshowcontext.hxx"
43 : #include "gdimtftools.hxx"
44 : #include "shape.hxx"
45 : #include "viewbackgroundshape.hxx"
46 :
47 :
48 : using namespace ::com::sun::star;
49 :
50 :
51 : namespace slideshow
52 : {
53 : namespace internal
54 : {
55 : /** Representation of a draw document's background shape.
56 :
57 : This class implements the Shape interface for the
58 : background shape. Since the background shape is neither
59 : animatable nor attributable, those more specialized
60 : derivations of the Shape interface are not implemented
61 : here.
62 :
63 : @attention this class is to be treated 'final', i.e. one
64 : should not derive from it.
65 : */
66 0 : class BackgroundShape : public Shape
67 : {
68 : public:
69 : /** Create the background shape.
70 :
71 : This method creates a shape that handles the
72 : peculiarities of the draw API regarding background
73 : content.
74 : */
75 : BackgroundShape( const ::com::sun::star::uno::Reference<
76 : ::com::sun::star::drawing::XDrawPage >& xDrawPage,
77 : const ::com::sun::star::uno::Reference<
78 : ::com::sun::star::drawing::XDrawPage >& xMasterPage,
79 : const SlideShowContext& rContext ); // throw ShapeLoadFailedException;
80 :
81 : virtual ::com::sun::star::uno::Reference<
82 : ::com::sun::star::drawing::XShape > getXShape() const SAL_OVERRIDE;
83 :
84 : // View layer methods
85 :
86 :
87 : virtual void addViewLayer( const ViewLayerSharedPtr& rNewLayer,
88 : bool bRedrawLayer ) SAL_OVERRIDE;
89 : virtual bool removeViewLayer( const ViewLayerSharedPtr& rNewLayer ) SAL_OVERRIDE;
90 : virtual bool clearAllViewLayers() SAL_OVERRIDE;
91 :
92 :
93 : // attribute methods
94 :
95 :
96 : virtual ::basegfx::B2DRectangle getBounds() const SAL_OVERRIDE;
97 : virtual ::basegfx::B2DRectangle getDomBounds() const SAL_OVERRIDE;
98 : virtual ::basegfx::B2DRectangle getUpdateArea() const SAL_OVERRIDE;
99 : virtual bool isVisible() const SAL_OVERRIDE;
100 : virtual double getPriority() const SAL_OVERRIDE;
101 : virtual bool isBackgroundDetached() const SAL_OVERRIDE;
102 :
103 :
104 : // render methods
105 :
106 :
107 : virtual bool update() const SAL_OVERRIDE;
108 : virtual bool render() const SAL_OVERRIDE;
109 : virtual bool isContentChanged() const SAL_OVERRIDE;
110 :
111 : private:
112 : /// The metafile actually representing the Shape
113 : GDIMetaFileSharedPtr mpMtf;
114 :
115 : // The attributes of this Shape
116 : ::basegfx::B2DRectangle maBounds; // always needed for rendering
117 :
118 : /// the list of active view shapes (one for each registered view layer)
119 : typedef ::std::vector< ViewBackgroundShapeSharedPtr > ViewBackgroundShapeVector;
120 : ViewBackgroundShapeVector maViewShapes;
121 : };
122 :
123 :
124 :
125 :
126 :
127 0 : BackgroundShape::BackgroundShape( const uno::Reference< drawing::XDrawPage >& xDrawPage,
128 : const uno::Reference< drawing::XDrawPage >& xMasterPage,
129 : const SlideShowContext& rContext ) :
130 : mpMtf(),
131 : maBounds(),
132 0 : maViewShapes()
133 : {
134 : uno::Reference< beans::XPropertySet > xPropSet( xDrawPage,
135 0 : uno::UNO_QUERY_THROW );
136 0 : GDIMetaFileSharedPtr pMtf( new GDIMetaFile() );
137 :
138 : // first try the page background (overrides
139 : // masterpage background), then try masterpage
140 0 : if( !getMetaFile( uno::Reference<lang::XComponent>(xDrawPage, uno::UNO_QUERY),
141 0 : xDrawPage, *pMtf, MTF_LOAD_BACKGROUND_ONLY,
142 0 : rContext.mxComponentContext ) &&
143 : !getMetaFile( uno::Reference<lang::XComponent>(xMasterPage, uno::UNO_QUERY),
144 0 : xDrawPage, *pMtf, MTF_LOAD_BACKGROUND_ONLY,
145 0 : rContext.mxComponentContext ))
146 : {
147 0 : throw ShapeLoadFailedException();
148 : }
149 :
150 : // there is a special background shape, add it
151 : // as the first one
152 :
153 :
154 0 : sal_Int32 nDocWidth=0;
155 0 : sal_Int32 nDocHeight=0;
156 0 : xPropSet->getPropertyValue("Width") >>= nDocWidth;
157 0 : xPropSet->getPropertyValue("Height") >>= nDocHeight;
158 :
159 0 : mpMtf = pMtf;
160 0 : maBounds = ::basegfx::B2DRectangle( 0,0,nDocWidth, nDocHeight );
161 0 : }
162 :
163 0 : uno::Reference< drawing::XShape > BackgroundShape::getXShape() const
164 : {
165 : // no real XShape representative
166 0 : return uno::Reference< drawing::XShape >();
167 : }
168 :
169 0 : void BackgroundShape::addViewLayer( const ViewLayerSharedPtr& rNewLayer,
170 : bool bRedrawLayer )
171 : {
172 : // already added?
173 0 : if( ::std::any_of( maViewShapes.begin(),
174 : maViewShapes.end(),
175 : ::boost::bind<bool>(
176 : ::std::equal_to< ViewLayerSharedPtr >(),
177 : ::boost::bind( &ViewBackgroundShape::getViewLayer,
178 : _1 ),
179 0 : ::boost::cref( rNewLayer ) ) ) )
180 : {
181 : // yes, nothing to do
182 0 : return;
183 : }
184 :
185 : maViewShapes.push_back(
186 : ViewBackgroundShapeSharedPtr(
187 : new ViewBackgroundShape( rNewLayer,
188 0 : maBounds ) ) );
189 :
190 : // render the Shape on the newly added ViewLayer
191 0 : if( bRedrawLayer )
192 0 : maViewShapes.back()->render( mpMtf );
193 : }
194 :
195 0 : bool BackgroundShape::removeViewLayer( const ViewLayerSharedPtr& rLayer )
196 : {
197 0 : const ViewBackgroundShapeVector::iterator aEnd( maViewShapes.end() );
198 :
199 : OSL_ENSURE( ::std::count_if(maViewShapes.begin(),
200 : aEnd,
201 : ::boost::bind<bool>(
202 : ::std::equal_to< ViewLayerSharedPtr >(),
203 : ::boost::bind( &ViewBackgroundShape::getViewLayer,
204 : _1 ),
205 : ::boost::cref( rLayer ) ) ) < 2,
206 : "BackgroundShape::removeViewLayer(): Duplicate ViewLayer entries!" );
207 :
208 0 : ViewBackgroundShapeVector::iterator aIter;
209 :
210 0 : if( (aIter=::std::remove_if( maViewShapes.begin(),
211 : aEnd,
212 : ::boost::bind<bool>(
213 : ::std::equal_to< ViewLayerSharedPtr >(),
214 : ::boost::bind( &ViewBackgroundShape::getViewLayer,
215 : _1 ),
216 0 : ::boost::cref( rLayer ) ) )) == aEnd )
217 : {
218 : // view layer seemingly was not added, failed
219 0 : return false;
220 : }
221 :
222 : // actually erase from container
223 0 : maViewShapes.erase( aIter, aEnd );
224 :
225 0 : return true;
226 : }
227 :
228 0 : bool BackgroundShape::clearAllViewLayers()
229 : {
230 0 : maViewShapes.clear();
231 0 : return true;
232 : }
233 :
234 0 : ::basegfx::B2DRectangle BackgroundShape::getBounds() const
235 : {
236 0 : return maBounds;
237 : }
238 :
239 0 : ::basegfx::B2DRectangle BackgroundShape::getDomBounds() const
240 : {
241 0 : return maBounds;
242 : }
243 :
244 0 : ::basegfx::B2DRectangle BackgroundShape::getUpdateArea() const
245 : {
246 : // TODO(F1): Need to expand background, too, when
247 : // antialiasing?
248 :
249 : // no transformation etc. possible for background shape
250 0 : return maBounds;
251 : }
252 :
253 0 : bool BackgroundShape::isVisible() const
254 : {
255 0 : return true;
256 : }
257 :
258 0 : double BackgroundShape::getPriority() const
259 : {
260 0 : return 0.0; // lowest prio, we're the background
261 : }
262 :
263 0 : bool BackgroundShape::update() const
264 : {
265 0 : return render();
266 : }
267 :
268 0 : bool BackgroundShape::render() const
269 : {
270 : SAL_INFO( "slideshow", "::presentation::internal::BackgroundShape::render()" );
271 : SAL_INFO( "slideshow", "::presentation::internal::BackgroundShape: 0x" << std::hex << this );
272 :
273 : // gcc again...
274 0 : const ::basegfx::B2DRectangle& rCurrBounds( BackgroundShape::getBounds() );
275 :
276 0 : if( rCurrBounds.getRange().equalZero() )
277 : {
278 : // zero-sized shapes are effectively invisible,
279 : // thus, we save us the rendering...
280 0 : return true;
281 : }
282 :
283 : // redraw all view shapes, by calling their render() method
284 0 : if( ::std::count_if( maViewShapes.begin(),
285 : maViewShapes.end(),
286 : ::boost::bind( &ViewBackgroundShape::render,
287 : _1,
288 0 : ::boost::cref( mpMtf ) ) )
289 0 : != static_cast<ViewBackgroundShapeVector::difference_type>(maViewShapes.size()) )
290 : {
291 : // at least one of the ViewBackgroundShape::render() calls did return
292 : // false - update failed on at least one ViewLayer
293 0 : return false;
294 : }
295 :
296 0 : return true;
297 : }
298 :
299 0 : bool BackgroundShape::isContentChanged() const
300 : {
301 0 : return false;
302 : }
303 :
304 0 : bool BackgroundShape::isBackgroundDetached() const
305 : {
306 0 : return false; // we're not animatable
307 : }
308 :
309 :
310 :
311 0 : ShapeSharedPtr createBackgroundShape(
312 : const uno::Reference< drawing::XDrawPage >& xDrawPage,
313 : const uno::Reference< drawing::XDrawPage >& xMasterPage,
314 : const SlideShowContext& rContext )
315 : {
316 : return ShapeSharedPtr(
317 : new BackgroundShape(
318 : xDrawPage,
319 : xMasterPage,
320 0 : rContext ));
321 : }
322 : }
323 3 : }
324 :
325 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|