1*70f497fbSAndrew Rist /************************************************************** 2cdf0e10cSrcweir * 3*70f497fbSAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 4*70f497fbSAndrew Rist * or more contributor license agreements. See the NOTICE file 5*70f497fbSAndrew Rist * distributed with this work for additional information 6*70f497fbSAndrew Rist * regarding copyright ownership. The ASF licenses this file 7*70f497fbSAndrew Rist * to you under the Apache License, Version 2.0 (the 8*70f497fbSAndrew Rist * "License"); you may not use this file except in compliance 9*70f497fbSAndrew Rist * with the License. You may obtain a copy of the License at 10*70f497fbSAndrew Rist * 11*70f497fbSAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12*70f497fbSAndrew Rist * 13*70f497fbSAndrew Rist * Unless required by applicable law or agreed to in writing, 14*70f497fbSAndrew Rist * software distributed under the License is distributed on an 15*70f497fbSAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*70f497fbSAndrew Rist * KIND, either express or implied. See the License for the 17*70f497fbSAndrew Rist * specific language governing permissions and limitations 18*70f497fbSAndrew Rist * under the License. 19*70f497fbSAndrew Rist * 20*70f497fbSAndrew Rist *************************************************************/ 21*70f497fbSAndrew Rist 22*70f497fbSAndrew Rist 23cdf0e10cSrcweir 24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 25cdf0e10cSrcweir #include "precompiled_slideshow.hxx" 26cdf0e10cSrcweir 27cdf0e10cSrcweir #include <canvas/debug.hxx> 28cdf0e10cSrcweir #include <tools/diagnose_ex.h> 29cdf0e10cSrcweir #include <canvas/canvastools.hxx> 30cdf0e10cSrcweir 31cdf0e10cSrcweir #include <math.h> 32cdf0e10cSrcweir 33cdf0e10cSrcweir #include <com/sun/star/beans/NamedValue.hpp> 34cdf0e10cSrcweir #include <com/sun/star/awt/Rectangle.hpp> 35cdf0e10cSrcweir #include <com/sun/star/animations/ValuePair.hpp> 36cdf0e10cSrcweir #include <com/sun/star/drawing/FillStyle.hpp> 37cdf0e10cSrcweir #include <com/sun/star/drawing/LineStyle.hpp> 38cdf0e10cSrcweir #include <com/sun/star/awt/FontSlant.hpp> 39cdf0e10cSrcweir 40cdf0e10cSrcweir #include <basegfx/polygon/b2dpolygon.hxx> 41cdf0e10cSrcweir #include <basegfx/polygon/b2dpolygontools.hxx> 42cdf0e10cSrcweir #include <basegfx/range/b2drange.hxx> 43cdf0e10cSrcweir #include <basegfx/vector/b2dvector.hxx> 44cdf0e10cSrcweir #include <basegfx/vector/b2ivector.hxx> 45cdf0e10cSrcweir #include <basegfx/matrix/b2dhommatrix.hxx> 46cdf0e10cSrcweir #include <basegfx/numeric/ftools.hxx> 47cdf0e10cSrcweir #include <basegfx/tools/lerp.hxx> 48cdf0e10cSrcweir #include <basegfx/matrix/b2dhommatrixtools.hxx> 49cdf0e10cSrcweir 50cdf0e10cSrcweir #include <cppcanvas/basegfxfactory.hxx> 51cdf0e10cSrcweir 52cdf0e10cSrcweir #include "unoview.hxx" 53cdf0e10cSrcweir #include "smilfunctionparser.hxx" 54cdf0e10cSrcweir #include "tools.hxx" 55cdf0e10cSrcweir 56cdf0e10cSrcweir #include <limits> 57cdf0e10cSrcweir 58cdf0e10cSrcweir 59cdf0e10cSrcweir using namespace ::com::sun::star; 60cdf0e10cSrcweir 61cdf0e10cSrcweir namespace slideshow 62cdf0e10cSrcweir { 63cdf0e10cSrcweir namespace internal 64cdf0e10cSrcweir { 65cdf0e10cSrcweir namespace 66cdf0e10cSrcweir { 67cdf0e10cSrcweir class NamedValueStringComparator 68cdf0e10cSrcweir { 69cdf0e10cSrcweir public: NamedValueStringComparator(const::rtl::OUString & rSearchString)70cdf0e10cSrcweir NamedValueStringComparator( const ::rtl::OUString& rSearchString ) : 71cdf0e10cSrcweir mrSearchString( rSearchString ) 72cdf0e10cSrcweir { 73cdf0e10cSrcweir } 74cdf0e10cSrcweir operator ()(const beans::NamedValue & rValue)75cdf0e10cSrcweir bool operator()( const beans::NamedValue& rValue ) 76cdf0e10cSrcweir { 77cdf0e10cSrcweir return rValue.Name == mrSearchString; 78cdf0e10cSrcweir } 79cdf0e10cSrcweir 80cdf0e10cSrcweir private: 81cdf0e10cSrcweir const ::rtl::OUString& mrSearchString; 82cdf0e10cSrcweir }; 83cdf0e10cSrcweir 84cdf0e10cSrcweir class NamedValueComparator 85cdf0e10cSrcweir { 86cdf0e10cSrcweir public: NamedValueComparator(const beans::NamedValue & rKey)87cdf0e10cSrcweir NamedValueComparator( const beans::NamedValue& rKey ) : 88cdf0e10cSrcweir mrKey( rKey ) 89cdf0e10cSrcweir { 90cdf0e10cSrcweir } 91cdf0e10cSrcweir operator ()(const beans::NamedValue & rValue)92cdf0e10cSrcweir bool operator()( const beans::NamedValue& rValue ) 93cdf0e10cSrcweir { 94cdf0e10cSrcweir return rValue.Name == mrKey.Name && rValue.Value == mrKey.Value; 95cdf0e10cSrcweir } 96cdf0e10cSrcweir 97cdf0e10cSrcweir private: 98cdf0e10cSrcweir const beans::NamedValue& mrKey; 99cdf0e10cSrcweir }; 100cdf0e10cSrcweir getAttributedShapeTransformation(const::basegfx::B2DRectangle & rShapeBounds,const ShapeAttributeLayerSharedPtr & pAttr)101cdf0e10cSrcweir ::basegfx::B2DHomMatrix getAttributedShapeTransformation( const ::basegfx::B2DRectangle& rShapeBounds, 102cdf0e10cSrcweir const ShapeAttributeLayerSharedPtr& pAttr ) 103cdf0e10cSrcweir { 104cdf0e10cSrcweir ::basegfx::B2DHomMatrix aTransform; 105cdf0e10cSrcweir const ::basegfx::B2DSize& rSize( rShapeBounds.getRange() ); 106cdf0e10cSrcweir 107cdf0e10cSrcweir const double nShearX( pAttr->isShearXAngleValid() ? 108cdf0e10cSrcweir pAttr->getShearXAngle() : 109cdf0e10cSrcweir 0.0 ); 110cdf0e10cSrcweir const double nShearY( pAttr->isShearYAngleValid() ? 111cdf0e10cSrcweir pAttr->getShearYAngle() : 112cdf0e10cSrcweir 0.0 ); 113cdf0e10cSrcweir const double nRotation( pAttr->isRotationAngleValid() ? 114cdf0e10cSrcweir pAttr->getRotationAngle()*M_PI/180.0 : 115cdf0e10cSrcweir 0.0 ); 116cdf0e10cSrcweir 117cdf0e10cSrcweir // scale, shear and rotation pivot point is the shape 118cdf0e10cSrcweir // center - adapt origin accordingly 119cdf0e10cSrcweir aTransform.translate( -0.5, -0.5 ); 120cdf0e10cSrcweir 121cdf0e10cSrcweir // ensure valid size (zero size will inevitably lead 122cdf0e10cSrcweir // to a singular transformation matrix) 123cdf0e10cSrcweir aTransform.scale( ::basegfx::pruneScaleValue( 124cdf0e10cSrcweir rSize.getX() ), 125cdf0e10cSrcweir ::basegfx::pruneScaleValue( 126cdf0e10cSrcweir rSize.getY() ) ); 127cdf0e10cSrcweir 128cdf0e10cSrcweir const bool bNeedShearX( !::basegfx::fTools::equalZero(nShearX) ); 129cdf0e10cSrcweir const bool bNeedShearY( !::basegfx::fTools::equalZero(nShearY) ); 130cdf0e10cSrcweir const bool bNeedRotation( !::basegfx::fTools::equalZero(nRotation) ); 131cdf0e10cSrcweir 132cdf0e10cSrcweir if( bNeedRotation || bNeedShearX || bNeedShearY ) 133cdf0e10cSrcweir { 134cdf0e10cSrcweir if( bNeedShearX ) 135cdf0e10cSrcweir aTransform.shearX( nShearX ); 136cdf0e10cSrcweir 137cdf0e10cSrcweir if( bNeedShearY ) 138cdf0e10cSrcweir aTransform.shearY( nShearY ); 139cdf0e10cSrcweir 140cdf0e10cSrcweir if( bNeedRotation ) 141cdf0e10cSrcweir aTransform.rotate( nRotation ); 142cdf0e10cSrcweir } 143cdf0e10cSrcweir 144cdf0e10cSrcweir // move left, top corner back to position of the 145cdf0e10cSrcweir // shape. Since we've already translated the 146cdf0e10cSrcweir // center of the shape to the origin (the 147cdf0e10cSrcweir // translate( -0.5, -0.5 ) above), translate to 148cdf0e10cSrcweir // center of final shape position here. 149cdf0e10cSrcweir aTransform.translate( rShapeBounds.getCenterX(), 150cdf0e10cSrcweir rShapeBounds.getCenterY() ); 151cdf0e10cSrcweir 152cdf0e10cSrcweir return aTransform; 153cdf0e10cSrcweir } 154cdf0e10cSrcweir } 155cdf0e10cSrcweir 156cdf0e10cSrcweir // Value extraction from Any 157cdf0e10cSrcweir // ========================= 158cdf0e10cSrcweir 159cdf0e10cSrcweir /// extract unary double value from Any extractValue(double & o_rValue,const uno::Any & rSourceAny,const ShapeSharedPtr & rShape,const::basegfx::B2DVector & rSlideBounds)160cdf0e10cSrcweir bool extractValue( double& o_rValue, 161cdf0e10cSrcweir const uno::Any& rSourceAny, 162cdf0e10cSrcweir const ShapeSharedPtr& rShape, 163cdf0e10cSrcweir const ::basegfx::B2DVector& rSlideBounds ) 164cdf0e10cSrcweir { 165cdf0e10cSrcweir // try to extract numeric value (double, or smaller POD, like float or int) 166cdf0e10cSrcweir if( (rSourceAny >>= o_rValue) ) 167cdf0e10cSrcweir { 168cdf0e10cSrcweir // succeeded 169cdf0e10cSrcweir return true; 170cdf0e10cSrcweir } 171cdf0e10cSrcweir 172cdf0e10cSrcweir // try to extract string 173cdf0e10cSrcweir ::rtl::OUString aString; 174cdf0e10cSrcweir if( !(rSourceAny >>= aString) ) 175cdf0e10cSrcweir return false; // nothing left to try 176cdf0e10cSrcweir 177cdf0e10cSrcweir // parse the string into an ExpressionNode 178cdf0e10cSrcweir try 179cdf0e10cSrcweir { 180cdf0e10cSrcweir // Parse string into ExpressionNode, eval node at time 0.0 181cdf0e10cSrcweir o_rValue = (*SmilFunctionParser::parseSmilValue( 182cdf0e10cSrcweir aString, 183cdf0e10cSrcweir calcRelativeShapeBounds(rSlideBounds, 184cdf0e10cSrcweir rShape->getBounds()) ))(0.0); 185cdf0e10cSrcweir } 186cdf0e10cSrcweir catch( ParseError& ) 187cdf0e10cSrcweir { 188cdf0e10cSrcweir return false; 189cdf0e10cSrcweir } 190cdf0e10cSrcweir 191cdf0e10cSrcweir return true; 192cdf0e10cSrcweir } 193cdf0e10cSrcweir 194cdf0e10cSrcweir /// extract enum/constant group value from Any extractValue(sal_Int32 & o_rValue,const uno::Any & rSourceAny,const ShapeSharedPtr &,const::basegfx::B2DVector &)195cdf0e10cSrcweir bool extractValue( sal_Int32& o_rValue, 196cdf0e10cSrcweir const uno::Any& rSourceAny, 197cdf0e10cSrcweir const ShapeSharedPtr& /*rShape*/, 198cdf0e10cSrcweir const ::basegfx::B2DVector& /*rSlideBounds*/ ) 199cdf0e10cSrcweir { 200cdf0e10cSrcweir // try to extract numeric value (int, or smaller POD, like byte) 201cdf0e10cSrcweir if( (rSourceAny >>= o_rValue) ) 202cdf0e10cSrcweir { 203cdf0e10cSrcweir // succeeded 204cdf0e10cSrcweir return true; 205cdf0e10cSrcweir } 206cdf0e10cSrcweir 207cdf0e10cSrcweir // okay, no plain int. Maybe one of the domain-specific enums? 208cdf0e10cSrcweir drawing::FillStyle eFillStyle; 209cdf0e10cSrcweir if( (rSourceAny >>= eFillStyle) ) 210cdf0e10cSrcweir { 211cdf0e10cSrcweir o_rValue = sal::static_int_cast<sal_Int16>(eFillStyle); 212cdf0e10cSrcweir 213cdf0e10cSrcweir // succeeded 214cdf0e10cSrcweir return true; 215cdf0e10cSrcweir } 216cdf0e10cSrcweir 217cdf0e10cSrcweir drawing::LineStyle eLineStyle; 218cdf0e10cSrcweir if( (rSourceAny >>= eLineStyle) ) 219cdf0e10cSrcweir { 220cdf0e10cSrcweir o_rValue = sal::static_int_cast<sal_Int16>(eLineStyle); 221cdf0e10cSrcweir 222cdf0e10cSrcweir // succeeded 223cdf0e10cSrcweir return true; 224cdf0e10cSrcweir } 225cdf0e10cSrcweir 226cdf0e10cSrcweir awt::FontSlant eFontSlant; 227cdf0e10cSrcweir if( (rSourceAny >>= eFontSlant) ) 228cdf0e10cSrcweir { 229cdf0e10cSrcweir o_rValue = sal::static_int_cast<sal_Int16>(eFontSlant); 230cdf0e10cSrcweir 231cdf0e10cSrcweir // succeeded 232cdf0e10cSrcweir return true; 233cdf0e10cSrcweir } 234cdf0e10cSrcweir 235cdf0e10cSrcweir // nothing left to try. Failure 236cdf0e10cSrcweir return false; 237cdf0e10cSrcweir } 238cdf0e10cSrcweir 239cdf0e10cSrcweir /// extract enum/constant group value from Any extractValue(sal_Int16 & o_rValue,const uno::Any & rSourceAny,const ShapeSharedPtr & rShape,const::basegfx::B2DVector & rSlideBounds)240cdf0e10cSrcweir bool extractValue( sal_Int16& o_rValue, 241cdf0e10cSrcweir const uno::Any& rSourceAny, 242cdf0e10cSrcweir const ShapeSharedPtr& rShape, 243cdf0e10cSrcweir const ::basegfx::B2DVector& rSlideBounds ) 244cdf0e10cSrcweir { 245cdf0e10cSrcweir sal_Int32 aValue; 246cdf0e10cSrcweir if( !extractValue(aValue,rSourceAny,rShape,rSlideBounds) ) 247cdf0e10cSrcweir return false; 248cdf0e10cSrcweir 249cdf0e10cSrcweir if( std::numeric_limits<sal_Int16>::max() < aValue || 250cdf0e10cSrcweir std::numeric_limits<sal_Int16>::min() > aValue ) 251cdf0e10cSrcweir { 252cdf0e10cSrcweir return false; 253cdf0e10cSrcweir } 254cdf0e10cSrcweir 255cdf0e10cSrcweir o_rValue = static_cast<sal_Int16>(aValue); 256cdf0e10cSrcweir 257cdf0e10cSrcweir return true; 258cdf0e10cSrcweir } 259cdf0e10cSrcweir 260cdf0e10cSrcweir /// extract color value from Any extractValue(RGBColor & o_rValue,const uno::Any & rSourceAny,const ShapeSharedPtr &,const::basegfx::B2DVector &)261cdf0e10cSrcweir bool extractValue( RGBColor& o_rValue, 262cdf0e10cSrcweir const uno::Any& rSourceAny, 263cdf0e10cSrcweir const ShapeSharedPtr& /*rShape*/, 264cdf0e10cSrcweir const ::basegfx::B2DVector& /*rSlideBounds*/ ) 265cdf0e10cSrcweir { 266cdf0e10cSrcweir // try to extract numeric value (double, or smaller POD, like float or int) 267cdf0e10cSrcweir { 268cdf0e10cSrcweir double nTmp = 0; 269cdf0e10cSrcweir if( (rSourceAny >>= nTmp) ) 270cdf0e10cSrcweir { 271cdf0e10cSrcweir sal_uInt32 aIntColor( static_cast< sal_uInt32 >(nTmp) ); 272cdf0e10cSrcweir 273cdf0e10cSrcweir // TODO(F2): Handle color values correctly, here 274cdf0e10cSrcweir o_rValue = unoColor2RGBColor( aIntColor ); 275cdf0e10cSrcweir 276cdf0e10cSrcweir // succeeded 277cdf0e10cSrcweir return true; 278cdf0e10cSrcweir } 279cdf0e10cSrcweir } 280cdf0e10cSrcweir 281cdf0e10cSrcweir // try double sequence 282cdf0e10cSrcweir { 283cdf0e10cSrcweir uno::Sequence< double > aTmp; 284cdf0e10cSrcweir if( (rSourceAny >>= aTmp) ) 285cdf0e10cSrcweir { 286cdf0e10cSrcweir ENSURE_OR_THROW( aTmp.getLength() == 3, 287cdf0e10cSrcweir "extractValue(): inappropriate length for RGB color value" ); 288cdf0e10cSrcweir 289cdf0e10cSrcweir o_rValue = RGBColor( aTmp[0], aTmp[1], aTmp[2] ); 290cdf0e10cSrcweir 291cdf0e10cSrcweir // succeeded 292cdf0e10cSrcweir return true; 293cdf0e10cSrcweir } 294cdf0e10cSrcweir } 295cdf0e10cSrcweir 296cdf0e10cSrcweir // try sal_Int32 sequence 297cdf0e10cSrcweir { 298cdf0e10cSrcweir uno::Sequence< sal_Int32 > aTmp; 299cdf0e10cSrcweir if( (rSourceAny >>= aTmp) ) 300cdf0e10cSrcweir { 301cdf0e10cSrcweir ENSURE_OR_THROW( aTmp.getLength() == 3, 302cdf0e10cSrcweir "extractValue(): inappropriate length for RGB color value" ); 303cdf0e10cSrcweir 304cdf0e10cSrcweir // truncate to byte 305cdf0e10cSrcweir o_rValue = RGBColor( ::cppcanvas::makeColor( 306cdf0e10cSrcweir static_cast<sal_uInt8>(aTmp[0]), 307cdf0e10cSrcweir static_cast<sal_uInt8>(aTmp[1]), 308cdf0e10cSrcweir static_cast<sal_uInt8>(aTmp[2]), 309cdf0e10cSrcweir 255 ) ); 310cdf0e10cSrcweir 311cdf0e10cSrcweir // succeeded 312cdf0e10cSrcweir return true; 313cdf0e10cSrcweir } 314cdf0e10cSrcweir } 315cdf0e10cSrcweir 316cdf0e10cSrcweir // try sal_Int8 sequence 317cdf0e10cSrcweir { 318cdf0e10cSrcweir uno::Sequence< sal_Int8 > aTmp; 319cdf0e10cSrcweir if( (rSourceAny >>= aTmp) ) 320cdf0e10cSrcweir { 321cdf0e10cSrcweir ENSURE_OR_THROW( aTmp.getLength() == 3, 322cdf0e10cSrcweir "extractValue(): inappropriate length for RGB color value" ); 323cdf0e10cSrcweir 324cdf0e10cSrcweir o_rValue = RGBColor( ::cppcanvas::makeColor( aTmp[0], aTmp[1], aTmp[2], 255 ) ); 325cdf0e10cSrcweir 326cdf0e10cSrcweir // succeeded 327cdf0e10cSrcweir return true; 328cdf0e10cSrcweir } 329cdf0e10cSrcweir } 330cdf0e10cSrcweir 331cdf0e10cSrcweir // try to extract string 332cdf0e10cSrcweir ::rtl::OUString aString; 333cdf0e10cSrcweir if( !(rSourceAny >>= aString) ) 334cdf0e10cSrcweir return false; // nothing left to try 335cdf0e10cSrcweir 336cdf0e10cSrcweir // TODO(F2): Provide symbolic color values here 337cdf0e10cSrcweir o_rValue = RGBColor( 0.5, 0.5, 0.5 ); 338cdf0e10cSrcweir 339cdf0e10cSrcweir return true; 340cdf0e10cSrcweir } 341cdf0e10cSrcweir 342cdf0e10cSrcweir /// extract color value from Any extractValue(HSLColor & o_rValue,const uno::Any & rSourceAny,const ShapeSharedPtr &,const::basegfx::B2DVector &)343cdf0e10cSrcweir bool extractValue( HSLColor& o_rValue, 344cdf0e10cSrcweir const uno::Any& rSourceAny, 345cdf0e10cSrcweir const ShapeSharedPtr& /*rShape*/, 346cdf0e10cSrcweir const ::basegfx::B2DVector& /*rSlideBounds*/ ) 347cdf0e10cSrcweir { 348cdf0e10cSrcweir // try double sequence 349cdf0e10cSrcweir { 350cdf0e10cSrcweir uno::Sequence< double > aTmp; 351cdf0e10cSrcweir if( (rSourceAny >>= aTmp) ) 352cdf0e10cSrcweir { 353cdf0e10cSrcweir ENSURE_OR_THROW( aTmp.getLength() == 3, 354cdf0e10cSrcweir "extractValue(): inappropriate length for HSL color value" ); 355cdf0e10cSrcweir 356cdf0e10cSrcweir o_rValue = HSLColor( aTmp[0], aTmp[1], aTmp[2] ); 357cdf0e10cSrcweir 358cdf0e10cSrcweir // succeeded 359cdf0e10cSrcweir return true; 360cdf0e10cSrcweir } 361cdf0e10cSrcweir } 362cdf0e10cSrcweir 363cdf0e10cSrcweir // try sal_Int8 sequence 364cdf0e10cSrcweir { 365cdf0e10cSrcweir uno::Sequence< sal_Int8 > aTmp; 366cdf0e10cSrcweir if( (rSourceAny >>= aTmp) ) 367cdf0e10cSrcweir { 368cdf0e10cSrcweir ENSURE_OR_THROW( aTmp.getLength() == 3, 369cdf0e10cSrcweir "extractValue(): inappropriate length for HSL color value" ); 370cdf0e10cSrcweir 371cdf0e10cSrcweir o_rValue = HSLColor( aTmp[0]*360.0/255.0, aTmp[1]/255.0, aTmp[2]/255.0 ); 372cdf0e10cSrcweir 373cdf0e10cSrcweir // succeeded 374cdf0e10cSrcweir return true; 375cdf0e10cSrcweir } 376cdf0e10cSrcweir } 377cdf0e10cSrcweir 378cdf0e10cSrcweir return false; // nothing left to try 379cdf0e10cSrcweir } 380cdf0e10cSrcweir 381cdf0e10cSrcweir /// extract plain string from Any extractValue(::rtl::OUString & o_rValue,const uno::Any & rSourceAny,const ShapeSharedPtr &,const::basegfx::B2DVector &)382cdf0e10cSrcweir bool extractValue( ::rtl::OUString& o_rValue, 383cdf0e10cSrcweir const uno::Any& rSourceAny, 384cdf0e10cSrcweir const ShapeSharedPtr& /*rShape*/, 385cdf0e10cSrcweir const ::basegfx::B2DVector& /*rSlideBounds*/ ) 386cdf0e10cSrcweir { 387cdf0e10cSrcweir // try to extract string 388cdf0e10cSrcweir if( !(rSourceAny >>= o_rValue) ) 389cdf0e10cSrcweir return false; // nothing left to try 390cdf0e10cSrcweir 391cdf0e10cSrcweir return true; 392cdf0e10cSrcweir } 393cdf0e10cSrcweir 394cdf0e10cSrcweir /// extract bool value from Any extractValue(bool & o_rValue,const uno::Any & rSourceAny,const ShapeSharedPtr &,const::basegfx::B2DVector &)395cdf0e10cSrcweir bool extractValue( bool& o_rValue, 396cdf0e10cSrcweir const uno::Any& rSourceAny, 397cdf0e10cSrcweir const ShapeSharedPtr& /*rShape*/, 398cdf0e10cSrcweir const ::basegfx::B2DVector& /*rSlideBounds*/ ) 399cdf0e10cSrcweir { 400cdf0e10cSrcweir sal_Bool nTmp = sal_Bool(); 401cdf0e10cSrcweir // try to extract bool value 402cdf0e10cSrcweir if( (rSourceAny >>= nTmp) ) 403cdf0e10cSrcweir { 404cdf0e10cSrcweir o_rValue = nTmp; 405cdf0e10cSrcweir 406cdf0e10cSrcweir // succeeded 407cdf0e10cSrcweir return true; 408cdf0e10cSrcweir } 409cdf0e10cSrcweir 410cdf0e10cSrcweir // try to extract string 411cdf0e10cSrcweir ::rtl::OUString aString; 412cdf0e10cSrcweir if( !(rSourceAny >>= aString) ) 413cdf0e10cSrcweir return false; // nothing left to try 414cdf0e10cSrcweir 415cdf0e10cSrcweir // we also take the strings "true" and "false", 416cdf0e10cSrcweir // as well as "on" and "off" here 417cdf0e10cSrcweir if( aString.equalsIgnoreAsciiCaseAscii("true") || 418cdf0e10cSrcweir aString.equalsIgnoreAsciiCaseAscii("on") ) 419cdf0e10cSrcweir { 420cdf0e10cSrcweir o_rValue = true; 421cdf0e10cSrcweir return true; 422cdf0e10cSrcweir } 423cdf0e10cSrcweir if( aString.equalsIgnoreAsciiCaseAscii("false") || 424cdf0e10cSrcweir aString.equalsIgnoreAsciiCaseAscii("off") ) 425cdf0e10cSrcweir { 426cdf0e10cSrcweir o_rValue = false; 427cdf0e10cSrcweir return true; 428cdf0e10cSrcweir } 429cdf0e10cSrcweir 430cdf0e10cSrcweir // ultimately failed. 431cdf0e10cSrcweir return false; 432cdf0e10cSrcweir } 433cdf0e10cSrcweir 434cdf0e10cSrcweir /// extract double 2-tuple from Any extractValue(::basegfx::B2DTuple & o_rPair,const uno::Any & rSourceAny,const ShapeSharedPtr & rShape,const::basegfx::B2DVector & rSlideBounds)435cdf0e10cSrcweir bool extractValue( ::basegfx::B2DTuple& o_rPair, 436cdf0e10cSrcweir const uno::Any& rSourceAny, 437cdf0e10cSrcweir const ShapeSharedPtr& rShape, 438cdf0e10cSrcweir const ::basegfx::B2DVector& rSlideBounds ) 439cdf0e10cSrcweir { 440cdf0e10cSrcweir animations::ValuePair aPair; 441cdf0e10cSrcweir 442cdf0e10cSrcweir if( !(rSourceAny >>= aPair) ) 443cdf0e10cSrcweir return false; 444cdf0e10cSrcweir 445cdf0e10cSrcweir double nFirst; 446cdf0e10cSrcweir if( !extractValue( nFirst, aPair.First, rShape, rSlideBounds ) ) 447cdf0e10cSrcweir return false; 448cdf0e10cSrcweir 449cdf0e10cSrcweir double nSecond; 450cdf0e10cSrcweir if( !extractValue( nSecond, aPair.Second, rShape, rSlideBounds ) ) 451cdf0e10cSrcweir return false; 452cdf0e10cSrcweir 453cdf0e10cSrcweir o_rPair.setX( nFirst ); 454cdf0e10cSrcweir o_rPair.setY( nSecond ); 455cdf0e10cSrcweir 456cdf0e10cSrcweir return true; 457cdf0e10cSrcweir } 458cdf0e10cSrcweir findNamedValue(uno::Sequence<beans::NamedValue> const & rSequence,const beans::NamedValue & rSearchKey)459cdf0e10cSrcweir bool findNamedValue( uno::Sequence< beans::NamedValue > const& rSequence, 460cdf0e10cSrcweir const beans::NamedValue& rSearchKey ) 461cdf0e10cSrcweir { 462cdf0e10cSrcweir const beans::NamedValue* pArray = rSequence.getConstArray(); 463cdf0e10cSrcweir const size_t nLen( rSequence.getLength() ); 464cdf0e10cSrcweir 465cdf0e10cSrcweir if( nLen == 0 ) 466cdf0e10cSrcweir return false; 467cdf0e10cSrcweir 468cdf0e10cSrcweir const beans::NamedValue* pFound = ::std::find_if( pArray, 469cdf0e10cSrcweir pArray + nLen, 470cdf0e10cSrcweir NamedValueComparator( rSearchKey ) ); 471cdf0e10cSrcweir 472cdf0e10cSrcweir if( pFound == pArray + nLen ) 473cdf0e10cSrcweir return false; 474cdf0e10cSrcweir 475cdf0e10cSrcweir return true; 476cdf0e10cSrcweir } 477cdf0e10cSrcweir findNamedValue(beans::NamedValue * o_pRet,const uno::Sequence<beans::NamedValue> & rSequence,const::rtl::OUString & rSearchString)478cdf0e10cSrcweir bool findNamedValue( beans::NamedValue* o_pRet, 479cdf0e10cSrcweir const uno::Sequence< beans::NamedValue >& rSequence, 480cdf0e10cSrcweir const ::rtl::OUString& rSearchString ) 481cdf0e10cSrcweir { 482cdf0e10cSrcweir const beans::NamedValue* pArray = rSequence.getConstArray(); 483cdf0e10cSrcweir const size_t nLen( rSequence.getLength() ); 484cdf0e10cSrcweir 485cdf0e10cSrcweir if( nLen == 0 ) 486cdf0e10cSrcweir return false; 487cdf0e10cSrcweir 488cdf0e10cSrcweir const beans::NamedValue* pFound = ::std::find_if( pArray, 489cdf0e10cSrcweir pArray + nLen, 490cdf0e10cSrcweir NamedValueStringComparator( rSearchString ) ); 491cdf0e10cSrcweir if( pFound == pArray + nLen ) 492cdf0e10cSrcweir return false; 493cdf0e10cSrcweir 494cdf0e10cSrcweir if( o_pRet ) 495cdf0e10cSrcweir *o_pRet = *pFound; 496cdf0e10cSrcweir 497cdf0e10cSrcweir return true; 498cdf0e10cSrcweir } 499cdf0e10cSrcweir calcRelativeShapeBounds(const basegfx::B2DVector & rPageSize,const basegfx::B2DRange & rShapeBounds)500cdf0e10cSrcweir basegfx::B2DRange calcRelativeShapeBounds( const basegfx::B2DVector& rPageSize, 501cdf0e10cSrcweir const basegfx::B2DRange& rShapeBounds ) 502cdf0e10cSrcweir { 503cdf0e10cSrcweir return basegfx::B2DRange( rShapeBounds.getMinX() / rPageSize.getX(), 504cdf0e10cSrcweir rShapeBounds.getMinY() / rPageSize.getY(), 505cdf0e10cSrcweir rShapeBounds.getMaxX() / rPageSize.getX(), 506cdf0e10cSrcweir rShapeBounds.getMaxY() / rPageSize.getY() ); 507cdf0e10cSrcweir } 508cdf0e10cSrcweir 509cdf0e10cSrcweir // TODO(F2): Currently, the positional attributes DO NOT mirror the XShape properties. 510cdf0e10cSrcweir // First and foremost, this is because we must operate with the shape boundrect, 511cdf0e10cSrcweir // not position and size (the conversion between logic rect, snap rect and boundrect 512cdf0e10cSrcweir // are non-trivial for draw shapes, and I won't duplicate them here). Thus, shapes 513cdf0e10cSrcweir // rotated on the page will still have 0.0 rotation angle, as the metafile 514cdf0e10cSrcweir // representation fetched over the API is our default zero case. 515cdf0e10cSrcweir getShapeTransformation(const::basegfx::B2DRectangle & rShapeBounds,const ShapeAttributeLayerSharedPtr & pAttr)516cdf0e10cSrcweir ::basegfx::B2DHomMatrix getShapeTransformation( const ::basegfx::B2DRectangle& rShapeBounds, 517cdf0e10cSrcweir const ShapeAttributeLayerSharedPtr& pAttr ) 518cdf0e10cSrcweir { 519cdf0e10cSrcweir if( !pAttr ) 520cdf0e10cSrcweir { 521cdf0e10cSrcweir const basegfx::B2DHomMatrix aTransform(basegfx::tools::createScaleTranslateB2DHomMatrix( 522cdf0e10cSrcweir rShapeBounds.getWidth(), rShapeBounds.getHeight(), 523cdf0e10cSrcweir rShapeBounds.getMinX(), rShapeBounds.getMinY())); 524cdf0e10cSrcweir 525cdf0e10cSrcweir return aTransform; 526cdf0e10cSrcweir } 527cdf0e10cSrcweir else 528cdf0e10cSrcweir { 529cdf0e10cSrcweir return getAttributedShapeTransformation( rShapeBounds, 530cdf0e10cSrcweir pAttr ); 531cdf0e10cSrcweir } 532cdf0e10cSrcweir } 533cdf0e10cSrcweir getSpriteTransformation(const::basegfx::B2DVector & rPixelSize,const::basegfx::B2DVector & rOrigSize,const ShapeAttributeLayerSharedPtr & pAttr)534cdf0e10cSrcweir ::basegfx::B2DHomMatrix getSpriteTransformation( const ::basegfx::B2DVector& rPixelSize, 535cdf0e10cSrcweir const ::basegfx::B2DVector& rOrigSize, 536cdf0e10cSrcweir const ShapeAttributeLayerSharedPtr& pAttr ) 537cdf0e10cSrcweir { 538cdf0e10cSrcweir ::basegfx::B2DHomMatrix aTransform; 539cdf0e10cSrcweir 540cdf0e10cSrcweir if( pAttr ) 541cdf0e10cSrcweir { 542cdf0e10cSrcweir const double nShearX( pAttr->isShearXAngleValid() ? 543cdf0e10cSrcweir pAttr->getShearXAngle() : 544cdf0e10cSrcweir 0.0 ); 545cdf0e10cSrcweir const double nShearY( pAttr->isShearYAngleValid() ? 546cdf0e10cSrcweir pAttr->getShearYAngle() : 547cdf0e10cSrcweir 0.0 ); 548cdf0e10cSrcweir const double nRotation( pAttr->isRotationAngleValid() ? 549cdf0e10cSrcweir pAttr->getRotationAngle()*M_PI/180.0 : 550cdf0e10cSrcweir 0.0 ); 551cdf0e10cSrcweir 552cdf0e10cSrcweir // scale, shear and rotation pivot point is the 553cdf0e10cSrcweir // sprite's pixel center - adapt origin accordingly 554cdf0e10cSrcweir aTransform.translate( -0.5*rPixelSize.getX(), 555cdf0e10cSrcweir -0.5*rPixelSize.getY() ); 556cdf0e10cSrcweir 557cdf0e10cSrcweir const ::basegfx::B2DSize aSize( 558cdf0e10cSrcweir pAttr->isWidthValid() ? pAttr->getWidth() : rOrigSize.getX(), 559cdf0e10cSrcweir pAttr->isHeightValid() ? pAttr->getHeight() : rOrigSize.getY() ); 560cdf0e10cSrcweir 561cdf0e10cSrcweir // ensure valid size (zero size will inevitably lead 562cdf0e10cSrcweir // to a singular transformation matrix). 563cdf0e10cSrcweir aTransform.scale( ::basegfx::pruneScaleValue( 564cdf0e10cSrcweir aSize.getX() / 565cdf0e10cSrcweir ::basegfx::pruneScaleValue( 566cdf0e10cSrcweir rOrigSize.getX() ) ), 567cdf0e10cSrcweir ::basegfx::pruneScaleValue( 568cdf0e10cSrcweir aSize.getY() / 569cdf0e10cSrcweir ::basegfx::pruneScaleValue( 570cdf0e10cSrcweir rOrigSize.getY() ) ) ); 571cdf0e10cSrcweir 572cdf0e10cSrcweir const bool bNeedShearX( !::basegfx::fTools::equalZero(nShearX) ); 573cdf0e10cSrcweir const bool bNeedShearY( !::basegfx::fTools::equalZero(nShearY) ); 574cdf0e10cSrcweir const bool bNeedRotation( !::basegfx::fTools::equalZero(nRotation) ); 575cdf0e10cSrcweir 576cdf0e10cSrcweir if( bNeedRotation || bNeedShearX || bNeedShearY ) 577cdf0e10cSrcweir { 578cdf0e10cSrcweir if( bNeedShearX ) 579cdf0e10cSrcweir aTransform.shearX( nShearX ); 580cdf0e10cSrcweir 581cdf0e10cSrcweir if( bNeedShearY ) 582cdf0e10cSrcweir aTransform.shearY( nShearY ); 583cdf0e10cSrcweir 584cdf0e10cSrcweir if( bNeedRotation ) 585cdf0e10cSrcweir aTransform.rotate( nRotation ); 586cdf0e10cSrcweir } 587cdf0e10cSrcweir 588cdf0e10cSrcweir // move left, top corner back to original position of 589cdf0e10cSrcweir // the sprite (we've translated the center of the 590cdf0e10cSrcweir // sprite to the origin above). 591cdf0e10cSrcweir aTransform.translate( 0.5*rPixelSize.getX(), 592cdf0e10cSrcweir 0.5*rPixelSize.getY() ); 593cdf0e10cSrcweir } 594cdf0e10cSrcweir 595cdf0e10cSrcweir // return identity transform for un-attributed 596cdf0e10cSrcweir // shapes. This renders the sprite as-is, in it's 597cdf0e10cSrcweir // document-supplied size. 598cdf0e10cSrcweir return aTransform; 599cdf0e10cSrcweir } 600cdf0e10cSrcweir getShapeUpdateArea(const::basegfx::B2DRectangle & rUnitBounds,const::basegfx::B2DHomMatrix & rShapeTransform,const ShapeAttributeLayerSharedPtr & pAttr)601cdf0e10cSrcweir ::basegfx::B2DRectangle getShapeUpdateArea( const ::basegfx::B2DRectangle& rUnitBounds, 602cdf0e10cSrcweir const ::basegfx::B2DHomMatrix& rShapeTransform, 603cdf0e10cSrcweir const ShapeAttributeLayerSharedPtr& pAttr ) 604cdf0e10cSrcweir { 605cdf0e10cSrcweir ::basegfx::B2DHomMatrix aTransform; 606cdf0e10cSrcweir 607cdf0e10cSrcweir if( pAttr && 608cdf0e10cSrcweir pAttr->isCharScaleValid() && 609cdf0e10cSrcweir fabs(pAttr->getCharScale()) > 1.0 ) 610cdf0e10cSrcweir { 611cdf0e10cSrcweir // enlarge shape bounds. Have to consider the worst 612cdf0e10cSrcweir // case here (the text fully fills the shape) 613cdf0e10cSrcweir 614cdf0e10cSrcweir const double nCharScale( pAttr->getCharScale() ); 615cdf0e10cSrcweir 616cdf0e10cSrcweir // center of scaling is the middle of the shape 617cdf0e10cSrcweir aTransform.translate( -0.5, -0.5 ); 618cdf0e10cSrcweir aTransform.scale( nCharScale, nCharScale ); 619cdf0e10cSrcweir aTransform.translate( 0.5, 0.5 ); 620cdf0e10cSrcweir } 621cdf0e10cSrcweir 622cdf0e10cSrcweir aTransform *= rShapeTransform; 623cdf0e10cSrcweir 624cdf0e10cSrcweir ::basegfx::B2DRectangle aRes; 625cdf0e10cSrcweir 626cdf0e10cSrcweir // apply shape transformation to unit rect 627cdf0e10cSrcweir return ::canvas::tools::calcTransformedRectBounds( 628cdf0e10cSrcweir aRes, 629cdf0e10cSrcweir rUnitBounds, 630cdf0e10cSrcweir aTransform ); 631cdf0e10cSrcweir } 632cdf0e10cSrcweir getShapeUpdateArea(const::basegfx::B2DRange & rUnitBounds,const::basegfx::B2DRange & rShapeBounds)633cdf0e10cSrcweir ::basegfx::B2DRange getShapeUpdateArea( const ::basegfx::B2DRange& rUnitBounds, 634cdf0e10cSrcweir const ::basegfx::B2DRange& rShapeBounds ) 635cdf0e10cSrcweir { 636cdf0e10cSrcweir return ::basegfx::B2DRectangle( 637cdf0e10cSrcweir basegfx::tools::lerp( rShapeBounds.getMinX(), 638cdf0e10cSrcweir rShapeBounds.getMaxX(), 639cdf0e10cSrcweir rUnitBounds.getMinX() ), 640cdf0e10cSrcweir basegfx::tools::lerp( rShapeBounds.getMinY(), 641cdf0e10cSrcweir rShapeBounds.getMaxY(), 642cdf0e10cSrcweir rUnitBounds.getMinY() ), 643cdf0e10cSrcweir basegfx::tools::lerp( rShapeBounds.getMinX(), 644cdf0e10cSrcweir rShapeBounds.getMaxX(), 645cdf0e10cSrcweir rUnitBounds.getMaxX() ), 646cdf0e10cSrcweir basegfx::tools::lerp( rShapeBounds.getMinY(), 647cdf0e10cSrcweir rShapeBounds.getMaxY(), 648cdf0e10cSrcweir rUnitBounds.getMaxY() ) ); 649cdf0e10cSrcweir } 650cdf0e10cSrcweir getShapePosSize(const::basegfx::B2DRectangle & rOrigBounds,const ShapeAttributeLayerSharedPtr & pAttr)651cdf0e10cSrcweir ::basegfx::B2DRectangle getShapePosSize( const ::basegfx::B2DRectangle& rOrigBounds, 652cdf0e10cSrcweir const ShapeAttributeLayerSharedPtr& pAttr ) 653cdf0e10cSrcweir { 654cdf0e10cSrcweir // an already empty shape bound need no further 655cdf0e10cSrcweir // treatment. In fact, any changes applied below would 656cdf0e10cSrcweir // actually remove the special empty state, thus, don't 657cdf0e10cSrcweir // change! 658cdf0e10cSrcweir if( !pAttr || 659cdf0e10cSrcweir rOrigBounds.isEmpty() ) 660cdf0e10cSrcweir { 661cdf0e10cSrcweir return rOrigBounds; 662cdf0e10cSrcweir } 663cdf0e10cSrcweir else 664cdf0e10cSrcweir { 665cdf0e10cSrcweir // cannot use maBounds anymore, attributes might have been 666cdf0e10cSrcweir // changed by now. 667cdf0e10cSrcweir // Have to use absolute values here, as negative sizes 668cdf0e10cSrcweir // (aka mirrored shapes) _still_ have the same bounds, 669cdf0e10cSrcweir // only with mirrored content. 670cdf0e10cSrcweir ::basegfx::B2DSize aSize; 671cdf0e10cSrcweir aSize.setX( fabs( pAttr->isWidthValid() ? 672cdf0e10cSrcweir pAttr->getWidth() : 673cdf0e10cSrcweir rOrigBounds.getWidth() ) ); 674cdf0e10cSrcweir aSize.setY( fabs( pAttr->isHeightValid() ? 675cdf0e10cSrcweir pAttr->getHeight() : 676cdf0e10cSrcweir rOrigBounds.getHeight() ) ); 677cdf0e10cSrcweir 678cdf0e10cSrcweir ::basegfx::B2DPoint aPos; 679cdf0e10cSrcweir aPos.setX( pAttr->isPosXValid() ? 680cdf0e10cSrcweir pAttr->getPosX() : 681cdf0e10cSrcweir rOrigBounds.getCenterX() ); 682cdf0e10cSrcweir aPos.setY( pAttr->isPosYValid() ? 683cdf0e10cSrcweir pAttr->getPosY() : 684cdf0e10cSrcweir rOrigBounds.getCenterY() ); 685cdf0e10cSrcweir 686cdf0e10cSrcweir // the positional attribute retrieved from the 687cdf0e10cSrcweir // ShapeAttributeLayer actually denotes the _middle_ 688cdf0e10cSrcweir // of the shape (do it as the PPTs do...) 689cdf0e10cSrcweir return ::basegfx::B2DRectangle( aPos - 0.5*aSize, 690cdf0e10cSrcweir aPos + 0.5*aSize ); 691cdf0e10cSrcweir } 692cdf0e10cSrcweir } 693cdf0e10cSrcweir unoColor2RGBColor(sal_Int32 nColor)694cdf0e10cSrcweir RGBColor unoColor2RGBColor( sal_Int32 nColor ) 695cdf0e10cSrcweir { 696cdf0e10cSrcweir return RGBColor( 697cdf0e10cSrcweir ::cppcanvas::makeColor( 698cdf0e10cSrcweir // convert from API color to IntSRGBA color 699cdf0e10cSrcweir // (0xAARRGGBB -> 0xRRGGBBAA) 700cdf0e10cSrcweir static_cast< sal_uInt8 >( nColor >> 16U ), 701cdf0e10cSrcweir static_cast< sal_uInt8 >( nColor >> 8U ), 702cdf0e10cSrcweir static_cast< sal_uInt8 >( nColor ), 703cdf0e10cSrcweir static_cast< sal_uInt8 >( nColor >> 24U ) ) ); 704cdf0e10cSrcweir } 705cdf0e10cSrcweir RGBAColor2UnoColor(::cppcanvas::Color::IntSRGBA aColor)706cdf0e10cSrcweir sal_Int32 RGBAColor2UnoColor( ::cppcanvas::Color::IntSRGBA aColor ) 707cdf0e10cSrcweir { 708cdf0e10cSrcweir return ::cppcanvas::makeColorARGB( 709cdf0e10cSrcweir // convert from IntSRGBA color to API color 710cdf0e10cSrcweir // (0xRRGGBBAA -> 0xAARRGGBB) 711cdf0e10cSrcweir static_cast< sal_uInt8 >(0), 712cdf0e10cSrcweir ::cppcanvas::getRed(aColor), 713cdf0e10cSrcweir ::cppcanvas::getGreen(aColor), 714cdf0e10cSrcweir ::cppcanvas::getBlue(aColor)); 715cdf0e10cSrcweir } 716cdf0e10cSrcweir 717cdf0e10cSrcweir /*sal_Int32 RGBAColor2UnoColor( ::cppcanvas::Color::IntSRGBA aColor ) 718cdf0e10cSrcweir { 719cdf0e10cSrcweir return ::cppcanvas::unMakeColor( 720cdf0e10cSrcweir // convert from IntSRGBA color to API color 721cdf0e10cSrcweir // (0xRRGGBBAA -> 0xAARRGGBB) 722cdf0e10cSrcweir static_cast< sal_uInt8 >(0), 723cdf0e10cSrcweir ::cppcanvas::getRed(aColor), 724cdf0e10cSrcweir ::cppcanvas::getGreen(aColor), 725cdf0e10cSrcweir ::cppcanvas::getBlue(aColor)); 726cdf0e10cSrcweir }*/ 727cdf0e10cSrcweir unSignedToSigned(sal_Int8 nInt)728cdf0e10cSrcweir sal_Int8 unSignedToSigned(sal_Int8 nInt) 729cdf0e10cSrcweir { 730cdf0e10cSrcweir if(nInt < 0 ){ 731cdf0e10cSrcweir sal_Int8 nInt2 = nInt >> 1U; 732cdf0e10cSrcweir return nInt2; 733cdf0e10cSrcweir }else{ 734cdf0e10cSrcweir return nInt; 735cdf0e10cSrcweir } 736cdf0e10cSrcweir } 737cdf0e10cSrcweir fillRect(const::cppcanvas::CanvasSharedPtr & rCanvas,const::basegfx::B2DRectangle & rRect,::cppcanvas::Color::IntSRGBA aFillColor)738cdf0e10cSrcweir void fillRect( const ::cppcanvas::CanvasSharedPtr& rCanvas, 739cdf0e10cSrcweir const ::basegfx::B2DRectangle& rRect, 740cdf0e10cSrcweir ::cppcanvas::Color::IntSRGBA aFillColor ) 741cdf0e10cSrcweir { 742cdf0e10cSrcweir const ::basegfx::B2DPolygon aPoly( 743cdf0e10cSrcweir ::basegfx::tools::createPolygonFromRect( rRect )); 744cdf0e10cSrcweir 745cdf0e10cSrcweir ::cppcanvas::PolyPolygonSharedPtr pPolyPoly( 746cdf0e10cSrcweir ::cppcanvas::BaseGfxFactory::getInstance().createPolyPolygon( rCanvas, 747cdf0e10cSrcweir aPoly ) ); 748cdf0e10cSrcweir 749cdf0e10cSrcweir if( pPolyPoly ) 750cdf0e10cSrcweir { 751cdf0e10cSrcweir pPolyPoly->setRGBAFillColor( aFillColor ); 752cdf0e10cSrcweir pPolyPoly->draw(); 753cdf0e10cSrcweir } 754cdf0e10cSrcweir } 755cdf0e10cSrcweir initSlideBackground(const::cppcanvas::CanvasSharedPtr & rCanvas,const::basegfx::B2ISize & rSize)756cdf0e10cSrcweir void initSlideBackground( const ::cppcanvas::CanvasSharedPtr& rCanvas, 757cdf0e10cSrcweir const ::basegfx::B2ISize& rSize ) 758cdf0e10cSrcweir { 759cdf0e10cSrcweir ::cppcanvas::CanvasSharedPtr pCanvas( rCanvas->clone() ); 760cdf0e10cSrcweir 761cdf0e10cSrcweir // set transformation to identitiy (->device pixel) 762cdf0e10cSrcweir pCanvas->setTransformation( ::basegfx::B2DHomMatrix() ); 763cdf0e10cSrcweir 764cdf0e10cSrcweir // #i42440# Fill the _full_ background in 765cdf0e10cSrcweir // black. Since we had to extend the bitmap by one 766cdf0e10cSrcweir // pixel, and the bitmap is initialized white, 767cdf0e10cSrcweir // depending on the slide content a one pixel wide 768cdf0e10cSrcweir // line will show to the bottom and the right. 769cdf0e10cSrcweir fillRect( pCanvas, 770cdf0e10cSrcweir ::basegfx::B2DRectangle( 0.0, 0.0, 771cdf0e10cSrcweir rSize.getX(), 772cdf0e10cSrcweir rSize.getY() ), 773cdf0e10cSrcweir 0x000000FFU ); 774cdf0e10cSrcweir 775cdf0e10cSrcweir // fill the bounds rectangle in white. Subtract one pixel 776cdf0e10cSrcweir // from both width and height, because the slide size is 777cdf0e10cSrcweir // chosen one pixel larger than given by the drawing 778cdf0e10cSrcweir // layer. This is because shapes with line style, that 779cdf0e10cSrcweir // have the size of the slide would otherwise be cut 780cdf0e10cSrcweir // off. OTOH, every other slide background (solid fill, 781cdf0e10cSrcweir // gradient, bitmap) render one pixel less, thus revealing 782cdf0e10cSrcweir // ugly white pixel to the right and the bottom. 783cdf0e10cSrcweir fillRect( pCanvas, 784cdf0e10cSrcweir ::basegfx::B2DRectangle( 0.0, 0.0, 785cdf0e10cSrcweir rSize.getX()-1, 786cdf0e10cSrcweir rSize.getY()-1 ), 787cdf0e10cSrcweir 0xFFFFFFFFU ); 788cdf0e10cSrcweir } 789cdf0e10cSrcweir getAPIShapeBounds(const uno::Reference<drawing::XShape> & xShape)790cdf0e10cSrcweir ::basegfx::B2DRectangle getAPIShapeBounds( const uno::Reference< drawing::XShape >& xShape ) 791cdf0e10cSrcweir { 792cdf0e10cSrcweir uno::Reference< beans::XPropertySet > xPropSet( xShape, 793cdf0e10cSrcweir uno::UNO_QUERY_THROW ); 794cdf0e10cSrcweir // read bound rect 795cdf0e10cSrcweir awt::Rectangle aTmpRect; 796cdf0e10cSrcweir if( !(xPropSet->getPropertyValue( 797cdf0e10cSrcweir ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("BoundRect") ) ) >>= aTmpRect) ) 798cdf0e10cSrcweir { 799cdf0e10cSrcweir ENSURE_OR_THROW( false, 800cdf0e10cSrcweir "getAPIShapeBounds(): Could not get \"BoundRect\" property from shape" ); 801cdf0e10cSrcweir } 802cdf0e10cSrcweir 803cdf0e10cSrcweir return ::basegfx::B2DRectangle( aTmpRect.X, 804cdf0e10cSrcweir aTmpRect.Y, 805cdf0e10cSrcweir aTmpRect.X+aTmpRect.Width, 806cdf0e10cSrcweir aTmpRect.Y+aTmpRect.Height ); 807cdf0e10cSrcweir } 808cdf0e10cSrcweir getAPIShapePrio(const uno::Reference<drawing::XShape> & xShape)809cdf0e10cSrcweir double getAPIShapePrio( const uno::Reference< drawing::XShape >& xShape ) 810cdf0e10cSrcweir { 811cdf0e10cSrcweir uno::Reference< beans::XPropertySet > xPropSet( xShape, 812cdf0e10cSrcweir uno::UNO_QUERY_THROW ); 813cdf0e10cSrcweir // read prio 814cdf0e10cSrcweir sal_Int32 nPrio(0); 815cdf0e10cSrcweir if( !(xPropSet->getPropertyValue( 816cdf0e10cSrcweir ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ZOrder") ) ) >>= nPrio) ) 817cdf0e10cSrcweir { 818cdf0e10cSrcweir ENSURE_OR_THROW( false, 819cdf0e10cSrcweir "getAPIShapePrio(): Could not get \"ZOrder\" property from shape" ); 820cdf0e10cSrcweir } 821cdf0e10cSrcweir 822cdf0e10cSrcweir // TODO(F2): Check and adapt the range of possible values here. 823cdf0e10cSrcweir // Maybe we can also take the total number of shapes here 824cdf0e10cSrcweir return nPrio / 65535.0; 825cdf0e10cSrcweir } 826cdf0e10cSrcweir getSlideSizePixel(const basegfx::B2DVector & rSlideSize,const UnoViewSharedPtr & pView)827cdf0e10cSrcweir basegfx::B2IVector getSlideSizePixel( const basegfx::B2DVector& rSlideSize, 828cdf0e10cSrcweir const UnoViewSharedPtr& pView ) 829cdf0e10cSrcweir { 830cdf0e10cSrcweir ENSURE_OR_THROW(pView, "getSlideSizePixel(): invalid view"); 831cdf0e10cSrcweir 832cdf0e10cSrcweir // determine transformed page bounds 833cdf0e10cSrcweir const basegfx::B2DRange aRect( 0,0, 834cdf0e10cSrcweir rSlideSize.getX(), 835cdf0e10cSrcweir rSlideSize.getY() ); 836cdf0e10cSrcweir basegfx::B2DRange aTmpRect; 837cdf0e10cSrcweir canvas::tools::calcTransformedRectBounds( aTmpRect, 838cdf0e10cSrcweir aRect, 839cdf0e10cSrcweir pView->getTransformation() ); 840cdf0e10cSrcweir 841cdf0e10cSrcweir // #i42440# Returned slide size is one pixel too small, as 842cdf0e10cSrcweir // rendering happens one pixel to the right and below the 843cdf0e10cSrcweir // actual bound rect. 844cdf0e10cSrcweir return basegfx::B2IVector( 845cdf0e10cSrcweir basegfx::fround( aTmpRect.getRange().getX() ) + 1, 846cdf0e10cSrcweir basegfx::fround( aTmpRect.getRange().getY() ) + 1 ); 847cdf0e10cSrcweir } 848cdf0e10cSrcweir } 849cdf0e10cSrcweir } 850