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 #include <drawinglayer/primitive2d/animatedprimitive2d.hxx> 21 #include <drawinglayer/animation/animationtiming.hxx> 22 #include <drawinglayer/primitive2d/transformprimitive2d.hxx> 23 #include <drawinglayer/geometry/viewinformation2d.hxx> 24 #include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx> 25 26 27 using namespace com::sun::star; 28 29 30 namespace drawinglayer 31 { 32 namespace primitive2d 33 { setAnimationEntry(const animation::AnimationEntry & rNew)34 void AnimatedSwitchPrimitive2D::setAnimationEntry(const animation::AnimationEntry& rNew) 35 { 36 // clone given animation description 37 mpAnimationEntry = rNew.clone(); 38 } 39 AnimatedSwitchPrimitive2D(const animation::AnimationEntry & rAnimationEntry,const Primitive2DContainer & rChildren,bool bIsTextAnimation)40 AnimatedSwitchPrimitive2D::AnimatedSwitchPrimitive2D( 41 const animation::AnimationEntry& rAnimationEntry, 42 const Primitive2DContainer& rChildren, 43 bool bIsTextAnimation) 44 : GroupPrimitive2D(rChildren), 45 mbIsTextAnimation(bIsTextAnimation) 46 { 47 // clone given animation description 48 mpAnimationEntry = rAnimationEntry.clone(); 49 } 50 ~AnimatedSwitchPrimitive2D()51 AnimatedSwitchPrimitive2D::~AnimatedSwitchPrimitive2D() 52 { 53 } 54 operator ==(const BasePrimitive2D & rPrimitive) const55 bool AnimatedSwitchPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const 56 { 57 if(GroupPrimitive2D::operator==(rPrimitive)) 58 { 59 const AnimatedSwitchPrimitive2D& rCompare = static_cast< const AnimatedSwitchPrimitive2D& >(rPrimitive); 60 61 return (getAnimationEntry() == rCompare.getAnimationEntry()); 62 } 63 64 return false; 65 } 66 get2DDecomposition(Primitive2DDecompositionVisitor & rVisitor,const geometry::ViewInformation2D & rViewInformation) const67 void AnimatedSwitchPrimitive2D::get2DDecomposition(Primitive2DDecompositionVisitor& rVisitor, const geometry::ViewInformation2D& rViewInformation) const 68 { 69 if(!getChildren().empty()) 70 { 71 const double fState(getAnimationEntry().getStateAtTime(rViewInformation.getViewTime())); 72 const sal_uInt32 nLen(getChildren().size()); 73 sal_uInt32 nIndex(basegfx::fround(fState * static_cast<double>(nLen))); 74 75 if(nIndex >= nLen) 76 { 77 nIndex = nLen - 1; 78 } 79 80 const Primitive2DReference xRef(getChildren()[nIndex], uno::UNO_SET_THROW); 81 rVisitor.append(xRef); 82 } 83 } 84 85 // provide unique ID 86 ImplPrimitive2DIDBlock(AnimatedSwitchPrimitive2D, PRIMITIVE2D_ID_ANIMATEDSWITCHPRIMITIVE2D) 87 88 } // end of namespace primitive2d 89 } // end of namespace drawinglayer 90 91 92 namespace drawinglayer 93 { 94 namespace primitive2d 95 { AnimatedBlinkPrimitive2D(const animation::AnimationEntry & rAnimationEntry,const Primitive2DContainer & rChildren)96 AnimatedBlinkPrimitive2D::AnimatedBlinkPrimitive2D( 97 const animation::AnimationEntry& rAnimationEntry, 98 const Primitive2DContainer& rChildren) 99 : AnimatedSwitchPrimitive2D(rAnimationEntry, rChildren, true/*bIsTextAnimation*/) 100 { 101 } 102 get2DDecomposition(Primitive2DDecompositionVisitor & rVisitor,const geometry::ViewInformation2D & rViewInformation) const103 void AnimatedBlinkPrimitive2D::get2DDecomposition(Primitive2DDecompositionVisitor& rVisitor, const geometry::ViewInformation2D& rViewInformation) const 104 { 105 if(!getChildren().empty()) 106 { 107 const double fState(getAnimationEntry().getStateAtTime(rViewInformation.getViewTime())); 108 109 if(fState < 0.5) 110 { 111 getChildren(rVisitor); 112 } 113 } 114 } 115 116 // provide unique ID 117 ImplPrimitive2DIDBlock(AnimatedBlinkPrimitive2D, PRIMITIVE2D_ID_ANIMATEDBLINKPRIMITIVE2D) 118 119 } // end of namespace primitive2d 120 } // end of namespace drawinglayer 121 122 123 namespace drawinglayer 124 { 125 namespace primitive2d 126 { AnimatedInterpolatePrimitive2D(const std::vector<basegfx::B2DHomMatrix> & rmMatrixStack,const animation::AnimationEntry & rAnimationEntry,const Primitive2DContainer & rChildren)127 AnimatedInterpolatePrimitive2D::AnimatedInterpolatePrimitive2D( 128 const std::vector< basegfx::B2DHomMatrix >& rmMatrixStack, 129 const animation::AnimationEntry& rAnimationEntry, 130 const Primitive2DContainer& rChildren) 131 : AnimatedSwitchPrimitive2D(rAnimationEntry, rChildren, true/*bIsTextAnimation*/), 132 maMatrixStack() 133 { 134 // copy matrices to locally pre-decomposed matrix stack 135 const sal_uInt32 nCount(rmMatrixStack.size()); 136 maMatrixStack.reserve(nCount); 137 138 for(sal_uInt32 a(0); a < nCount; a++) 139 { 140 maMatrixStack.emplace_back(rmMatrixStack[a]); 141 } 142 } 143 get2DDecomposition(Primitive2DDecompositionVisitor & rVisitor,const geometry::ViewInformation2D & rViewInformation) const144 void AnimatedInterpolatePrimitive2D::get2DDecomposition(Primitive2DDecompositionVisitor& rVisitor, const geometry::ViewInformation2D& rViewInformation) const 145 { 146 const sal_uInt32 nSize(maMatrixStack.size()); 147 148 if(nSize) 149 { 150 double fState(getAnimationEntry().getStateAtTime(rViewInformation.getViewTime())); 151 152 if(fState < 0.0) 153 { 154 fState = 0.0; 155 } 156 else if(fState > 1.0) 157 { 158 fState = 1.0; 159 } 160 161 const double fIndex(fState * static_cast<double>(nSize - 1)); 162 const sal_uInt32 nIndA(sal_uInt32(floor(fIndex))); 163 const double fOffset(fIndex - static_cast<double>(nIndA)); 164 basegfx::B2DHomMatrix aTargetTransform; 165 std::vector< basegfx::utils::B2DHomMatrixBufferedDecompose >::const_iterator aMatA(maMatrixStack.begin() + nIndA); 166 167 if(basegfx::fTools::equalZero(fOffset)) 168 { 169 // use matrix from nIndA directly 170 aTargetTransform = aMatA->getB2DHomMatrix(); 171 } 172 else 173 { 174 // interpolate. Get involved buffered decomposed matrices 175 const sal_uInt32 nIndB((nIndA + 1) % nSize); 176 std::vector< basegfx::utils::B2DHomMatrixBufferedDecompose >::const_iterator aMatB(maMatrixStack.begin() + nIndB); 177 178 // interpolate for fOffset [0.0 .. 1.0[ 179 const basegfx::B2DVector aScale(basegfx::interpolate(aMatA->getScale(), aMatB->getScale(), fOffset)); 180 const basegfx::B2DVector aTranslate(basegfx::interpolate(aMatA->getTranslate(), aMatB->getTranslate(), fOffset)); 181 const double fRotate(((aMatB->getRotate() - aMatA->getRotate()) * fOffset) + aMatA->getRotate()); 182 const double fShearX(((aMatB->getShearX() - aMatA->getShearX()) * fOffset) + aMatA->getShearX()); 183 184 // build matrix for state 185 aTargetTransform = basegfx::utils::createScaleShearXRotateTranslateB2DHomMatrix( 186 aScale, fShearX, fRotate, aTranslate); 187 } 188 189 // create new transform primitive reference, return new sequence 190 const Primitive2DReference xRef(new TransformPrimitive2D(aTargetTransform, getChildren())); 191 rVisitor.append(xRef); 192 } 193 else 194 { 195 getChildren(rVisitor); 196 } 197 } 198 199 // provide unique ID 200 ImplPrimitive2DIDBlock(AnimatedInterpolatePrimitive2D, PRIMITIVE2D_ID_ANIMATEDINTERPOLATEPRIMITIVE2D) 201 202 } // end of namespace primitive2d 203 } // end of namespace drawinglayer 204 205 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ 206