| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| // MARKER(update_precomp.py): autogen include statement, do not remove |
| #include "precompiled_slideshow.hxx" |
| |
| // must be first |
| #include <canvas/debug.hxx> |
| |
| #include <com/sun/star/awt/Rectangle.hpp> |
| #include <com/sun/star/beans/XPropertySet.hpp> |
| #include <com/sun/star/awt/FontWeight.hpp> |
| #include <rtl/logfile.hxx> |
| |
| #include <vcl/metaact.hxx> |
| #include <vcl/gdimtf.hxx> |
| |
| #include <basegfx/numeric/ftools.hxx> |
| |
| #include <boost/bind.hpp> |
| |
| #include <cmath> // for trigonometry and fabs |
| #include <algorithm> |
| #include <functional> |
| #include <limits> |
| |
| #include "backgroundshape.hxx" |
| #include "slideshowexceptions.hxx" |
| #include "slideshowcontext.hxx" |
| #include "gdimtftools.hxx" |
| #include "shape.hxx" |
| #include "viewbackgroundshape.hxx" |
| |
| |
| using namespace ::com::sun::star; |
| |
| |
| namespace slideshow |
| { |
| namespace internal |
| { |
| /** Representation of a draw document's background shape. |
| |
| This class implements the Shape interface for the |
| background shape. Since the background shape is neither |
| animatable nor attributable, those more specialized |
| derivations of the Shape interface are not implemented |
| here. |
| |
| @attention this class is to be treated 'final', i.e. one |
| should not derive from it. |
| */ |
| class BackgroundShape : public Shape |
| { |
| public: |
| /** Create the background shape. |
| |
| This method creates a shape that handles the |
| peculiarities of the draw API regarding background |
| content. |
| */ |
| BackgroundShape( const ::com::sun::star::uno::Reference< |
| ::com::sun::star::drawing::XDrawPage >& xDrawPage, |
| const ::com::sun::star::uno::Reference< |
| ::com::sun::star::drawing::XDrawPage >& xMasterPage, |
| const SlideShowContext& rContext ); // throw ShapeLoadFailedException; |
| |
| virtual ::com::sun::star::uno::Reference< |
| ::com::sun::star::drawing::XShape > getXShape() const; |
| |
| // View layer methods |
| //------------------------------------------------------------------ |
| |
| virtual void addViewLayer( const ViewLayerSharedPtr& rNewLayer, |
| bool bRedrawLayer ); |
| virtual bool removeViewLayer( const ViewLayerSharedPtr& rNewLayer ); |
| virtual bool clearAllViewLayers(); |
| |
| |
| // attribute methods |
| //------------------------------------------------------------------ |
| |
| virtual ::basegfx::B2DRectangle getBounds() const; |
| virtual ::basegfx::B2DRectangle getDomBounds() const; |
| virtual ::basegfx::B2DRectangle getUpdateArea() const; |
| virtual bool isVisible() const; |
| virtual double getPriority() const; |
| virtual bool isBackgroundDetached() const; |
| |
| |
| // render methods |
| //------------------------------------------------------------------ |
| |
| virtual bool update() const; |
| virtual bool render() const; |
| virtual bool isContentChanged() const; |
| |
| private: |
| /// The metafile actually representing the Shape |
| GDIMetaFileSharedPtr mpMtf; |
| |
| // The attributes of this Shape |
| ::basegfx::B2DRectangle maBounds; // always needed for rendering |
| |
| /// the list of active view shapes (one for each registered view layer) |
| typedef ::std::vector< ViewBackgroundShapeSharedPtr > ViewBackgroundShapeVector; |
| ViewBackgroundShapeVector maViewShapes; |
| }; |
| |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| |
| |
| BackgroundShape::BackgroundShape( const uno::Reference< drawing::XDrawPage >& xDrawPage, |
| const uno::Reference< drawing::XDrawPage >& xMasterPage, |
| const SlideShowContext& rContext ) : |
| mpMtf(), |
| maBounds(), |
| maViewShapes() |
| { |
| uno::Reference< beans::XPropertySet > xPropSet( xDrawPage, |
| uno::UNO_QUERY_THROW ); |
| GDIMetaFileSharedPtr pMtf( new GDIMetaFile() ); |
| |
| // first try the page background (overrides |
| // masterpage background), then try masterpage |
| if( !getMetaFile( uno::Reference<lang::XComponent>(xDrawPage, uno::UNO_QUERY), |
| xDrawPage, *pMtf, MTF_LOAD_BACKGROUND_ONLY, |
| rContext.mxComponentContext ) && |
| !getMetaFile( uno::Reference<lang::XComponent>(xMasterPage, uno::UNO_QUERY), |
| xDrawPage, *pMtf, MTF_LOAD_BACKGROUND_ONLY, |
| rContext.mxComponentContext )) |
| { |
| throw ShapeLoadFailedException(); |
| } |
| |
| // there is a special background shape, add it |
| // as the first one |
| // --------------------------------------------------- |
| |
| sal_Int32 nDocWidth=0; |
| sal_Int32 nDocHeight=0; |
| xPropSet->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Width") ) ) >>= nDocWidth; |
| xPropSet->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Height") ) ) >>= nDocHeight; |
| |
| mpMtf = pMtf; |
| maBounds = ::basegfx::B2DRectangle( 0,0,nDocWidth, nDocHeight ); |
| } |
| |
| uno::Reference< drawing::XShape > BackgroundShape::getXShape() const |
| { |
| // no real XShape representative |
| return uno::Reference< drawing::XShape >(); |
| } |
| |
| void BackgroundShape::addViewLayer( const ViewLayerSharedPtr& rNewLayer, |
| bool bRedrawLayer ) |
| { |
| ViewBackgroundShapeVector::iterator aEnd( maViewShapes.end() ); |
| |
| // already added? |
| if( ::std::find_if( maViewShapes.begin(), |
| aEnd, |
| ::boost::bind<bool>( |
| ::std::equal_to< ViewLayerSharedPtr >(), |
| ::boost::bind( &ViewBackgroundShape::getViewLayer, |
| _1 ), |
| ::boost::cref( rNewLayer ) ) ) != aEnd ) |
| { |
| // yes, nothing to do |
| return; |
| } |
| |
| maViewShapes.push_back( |
| ViewBackgroundShapeSharedPtr( |
| new ViewBackgroundShape( rNewLayer, |
| maBounds ) ) ); |
| |
| // render the Shape on the newly added ViewLayer |
| if( bRedrawLayer ) |
| maViewShapes.back()->render( mpMtf ); |
| } |
| |
| bool BackgroundShape::removeViewLayer( const ViewLayerSharedPtr& rLayer ) |
| { |
| const ViewBackgroundShapeVector::iterator aEnd( maViewShapes.end() ); |
| |
| OSL_ENSURE( ::std::count_if(maViewShapes.begin(), |
| aEnd, |
| ::boost::bind<bool>( |
| ::std::equal_to< ViewLayerSharedPtr >(), |
| ::boost::bind( &ViewBackgroundShape::getViewLayer, |
| _1 ), |
| ::boost::cref( rLayer ) ) ) < 2, |
| "BackgroundShape::removeViewLayer(): Duplicate ViewLayer entries!" ); |
| |
| ViewBackgroundShapeVector::iterator aIter; |
| |
| if( (aIter=::std::remove_if( maViewShapes.begin(), |
| aEnd, |
| ::boost::bind<bool>( |
| ::std::equal_to< ViewLayerSharedPtr >(), |
| ::boost::bind( &ViewBackgroundShape::getViewLayer, |
| _1 ), |
| ::boost::cref( rLayer ) ) )) == aEnd ) |
| { |
| // view layer seemingly was not added, failed |
| return false; |
| } |
| |
| // actually erase from container |
| maViewShapes.erase( aIter, aEnd ); |
| |
| return true; |
| } |
| |
| bool BackgroundShape::clearAllViewLayers() |
| { |
| maViewShapes.clear(); |
| return true; |
| } |
| |
| ::basegfx::B2DRectangle BackgroundShape::getBounds() const |
| { |
| return maBounds; |
| } |
| |
| ::basegfx::B2DRectangle BackgroundShape::getDomBounds() const |
| { |
| return maBounds; |
| } |
| |
| ::basegfx::B2DRectangle BackgroundShape::getUpdateArea() const |
| { |
| // TODO(F1): Need to expand background, too, when |
| // antialiasing? |
| |
| // no transformation etc. possible for background shape |
| return maBounds; |
| } |
| |
| bool BackgroundShape::isVisible() const |
| { |
| return true; |
| } |
| |
| double BackgroundShape::getPriority() const |
| { |
| return 0.0; // lowest prio, we're the background |
| } |
| |
| bool BackgroundShape::update() const |
| { |
| return render(); |
| } |
| |
| bool BackgroundShape::render() const |
| { |
| RTL_LOGFILE_CONTEXT( aLog, "::presentation::internal::BackgroundShape::render()" ); |
| RTL_LOGFILE_CONTEXT_TRACE1( aLog, "::presentation::internal::BackgroundShape: 0x%X", this ); |
| |
| // gcc again... |
| const ::basegfx::B2DRectangle& rCurrBounds( BackgroundShape::getBounds() ); |
| |
| if( rCurrBounds.getRange().equalZero() ) |
| { |
| // zero-sized shapes are effectively invisible, |
| // thus, we save us the rendering... |
| return true; |
| } |
| |
| // redraw all view shapes, by calling their render() method |
| if( ::std::count_if( maViewShapes.begin(), |
| maViewShapes.end(), |
| ::boost::bind( &ViewBackgroundShape::render, |
| _1, |
| ::boost::cref( mpMtf ) ) ) |
| != static_cast<ViewBackgroundShapeVector::difference_type>(maViewShapes.size()) ) |
| { |
| // at least one of the ViewBackgroundShape::render() calls did return |
| // false - update failed on at least one ViewLayer |
| return false; |
| } |
| |
| return true; |
| } |
| |
| bool BackgroundShape::isContentChanged() const |
| { |
| return false; |
| } |
| |
| bool BackgroundShape::isBackgroundDetached() const |
| { |
| return false; // we're not animatable |
| } |
| |
| ////////////////////////////////////////////////////////// |
| |
| ShapeSharedPtr createBackgroundShape( |
| const uno::Reference< drawing::XDrawPage >& xDrawPage, |
| const uno::Reference< drawing::XDrawPage >& xMasterPage, |
| const SlideShowContext& rContext ) |
| { |
| return ShapeSharedPtr( |
| new BackgroundShape( |
| xDrawPage, |
| xMasterPage, |
| rContext )); |
| } |
| } |
| } |