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