1 /* 2 * Copyright (c) 2013, Google Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are 6 * met: 7 * 8 * * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * * Redistributions in binary form must reproduce the above 11 * copyright notice, this list of conditions and the following disclaimer 12 * in the documentation and/or other materials provided with the 13 * distribution. 14 * * Neither the name of Google Inc. nor the names of its 15 * contributors may be used to endorse or promote products derived from 16 * this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31 #include "config.h" 32 #include "core/platform/animation/TimingFunctionTestHelper.h" 33 34 35 namespace WebCore { 36 37 // This class exists so that ChainedTimingFunction only needs to friend one thing. 38 class ChainedTimingFunctionTestHelper { 39 static void PrintTo(const ChainedTimingFunction& timingFunction, ::std::ostream* os) 40 { 41 // Forward declare the generic PrintTo function as ChainedTimingFunction needs to call it. 42 void PrintTo(const TimingFunction&, ::std::ostream*); 43 44 *os << "ChainedTimingFunction@" << &timingFunction << "("; 45 for (size_t i = 0; i < timingFunction.m_segments.size(); i++) { 46 ChainedTimingFunction::Segment segment = timingFunction.m_segments[i]; 47 PrintTo(*(segment.m_timingFunction.get()), os); 48 *os << "[" << segment.m_min << " -> " << segment.m_max << "]"; 49 if (i+1 != timingFunction.m_segments.size()) { 50 *os << ", "; 51 } 52 } 53 *os << ")"; 54 } 55 56 static bool equals(const ChainedTimingFunction& lhs, const TimingFunction& rhs) 57 { 58 if (rhs.type() != TimingFunction::ChainedFunction) 59 return false; 60 61 if (&lhs == &rhs) 62 return true; 63 64 const ChainedTimingFunction& ctf = toChainedTimingFunction(rhs); 65 if (lhs.m_segments.size() != ctf.m_segments.size()) 66 return false; 67 68 for (size_t i = 0; i < lhs.m_segments.size(); i++) { 69 if (!equals(lhs.m_segments[i], ctf.m_segments[i])) 70 return false; 71 } 72 return true; 73 } 74 75 static bool equals(const ChainedTimingFunction::Segment& lhs, const ChainedTimingFunction::Segment& rhs) 76 { 77 if (&lhs == &rhs) 78 return true; 79 80 if ((lhs.m_min != rhs.m_min) || (lhs.m_max != rhs.m_max)) 81 return false; 82 83 if (lhs.m_timingFunction == rhs.m_timingFunction) 84 return true; 85 86 ASSERT(lhs.m_timingFunction); 87 ASSERT(rhs.m_timingFunction); 88 89 return (*(lhs.m_timingFunction.get())) == (*(rhs.m_timingFunction.get())); 90 } 91 92 friend void PrintTo(const ChainedTimingFunction&, ::std::ostream*); 93 friend bool operator==(const ChainedTimingFunction& lhs, const TimingFunction& rhs); 94 }; 95 96 void PrintTo(const LinearTimingFunction& timingFunction, ::std::ostream* os) 97 { 98 *os << "LinearTimingFunction@" << &timingFunction; 99 } 100 101 void PrintTo(const CubicBezierTimingFunction& timingFunction, ::std::ostream* os) 102 { 103 *os << "CubicBezierTimingFunction@" << &timingFunction << "("; 104 switch (timingFunction.subType()) { 105 case CubicBezierTimingFunction::Ease: 106 *os << "Ease"; 107 break; 108 case CubicBezierTimingFunction::EaseIn: 109 *os << "EaseIn"; 110 break; 111 case CubicBezierTimingFunction::EaseOut: 112 *os << "EaseOut"; 113 break; 114 case CubicBezierTimingFunction::EaseInOut: 115 *os << "EaseInOut"; 116 break; 117 case CubicBezierTimingFunction::Custom: 118 *os << "Custom"; 119 break; 120 default: 121 ASSERT_NOT_REACHED(); 122 } 123 *os << ", " << timingFunction.x1(); 124 *os << ", " << timingFunction.y1(); 125 *os << ", " << timingFunction.x2(); 126 *os << ", " << timingFunction.y2(); 127 *os << ")"; 128 } 129 130 void PrintTo(const StepsTimingFunction& timingFunction, ::std::ostream* os) 131 { 132 *os << "StepsTimingFunction@" << &timingFunction << "("; 133 switch (timingFunction.subType()) { 134 case StepsTimingFunction::Start: 135 *os << "Start"; 136 break; 137 case StepsTimingFunction::End: 138 *os << "End"; 139 break; 140 case StepsTimingFunction::Custom: 141 *os << "Custom"; 142 break; 143 default: 144 ASSERT_NOT_REACHED(); 145 } 146 *os << ", " << timingFunction.numberOfSteps(); 147 *os << ", " << (timingFunction.stepAtStart() ? "true" : "false"); 148 *os << ")"; 149 } 150 151 void PrintTo(const ChainedTimingFunction& timingFunction, ::std::ostream* os) 152 { 153 ChainedTimingFunctionTestHelper::PrintTo(timingFunction, os); 154 } 155 156 // The generic PrintTo *must* come after the non-generic PrintTo otherwise it 157 // will end up calling itself. 158 void PrintTo(const TimingFunction& timingFunction, ::std::ostream* os) 159 { 160 switch (timingFunction.type()) { 161 case TimingFunction::LinearFunction: { 162 const LinearTimingFunction& linear = toLinearTimingFunction(timingFunction); 163 PrintTo(linear, os); 164 return; 165 } 166 case TimingFunction::CubicBezierFunction: { 167 const CubicBezierTimingFunction& cubic = toCubicBezierTimingFunction(timingFunction); 168 PrintTo(cubic, os); 169 return; 170 } 171 case TimingFunction::StepsFunction: { 172 const StepsTimingFunction& step = toStepsTimingFunction(timingFunction); 173 PrintTo(step, os); 174 return; 175 } 176 case TimingFunction::ChainedFunction: { 177 const ChainedTimingFunction& chained = toChainedTimingFunction(timingFunction); 178 PrintTo(chained, os); 179 return; 180 } 181 default: 182 ASSERT_NOT_REACHED(); 183 } 184 } 185 186 bool operator==(const LinearTimingFunction& lhs, const TimingFunction& rhs) 187 { 188 return rhs.type() == TimingFunction::LinearFunction; 189 } 190 191 bool operator==(const CubicBezierTimingFunction& lhs, const TimingFunction& rhs) 192 { 193 if (rhs.type() != TimingFunction::CubicBezierFunction) 194 return false; 195 196 const CubicBezierTimingFunction& ctf = toCubicBezierTimingFunction(rhs); 197 if ((lhs.subType() == CubicBezierTimingFunction::Custom) && (ctf.subType() == CubicBezierTimingFunction::Custom)) 198 return (lhs.x1() == ctf.x1()) && (lhs.y1() == ctf.y1()) && (lhs.x2() == ctf.x2()) && (lhs.y2() == ctf.y2()); 199 200 return lhs.subType() == ctf.subType(); 201 } 202 203 bool operator==(const StepsTimingFunction& lhs, const TimingFunction& rhs) 204 { 205 if (rhs.type() != TimingFunction::StepsFunction) 206 return false; 207 208 const StepsTimingFunction& stf = toStepsTimingFunction(rhs); 209 if ((lhs.subType() == StepsTimingFunction::Custom) && (stf.subType() == StepsTimingFunction::Custom)) 210 return (lhs.numberOfSteps() == stf.numberOfSteps()) && (lhs.stepAtStart() == stf.stepAtStart()); 211 212 return lhs.subType() == stf.subType(); 213 } 214 215 bool operator==(const ChainedTimingFunction& lhs, const TimingFunction& rhs) 216 { 217 return ChainedTimingFunctionTestHelper::equals(lhs, rhs); 218 } 219 220 // Like in the PrintTo case, the generic operator== *must* come after the 221 // non-generic operator== otherwise it will end up calling itself. 222 bool operator==(const TimingFunction& lhs, const TimingFunction& rhs) 223 { 224 switch (lhs.type()) { 225 case TimingFunction::LinearFunction: { 226 const LinearTimingFunction& linear = toLinearTimingFunction(lhs); 227 return (linear == rhs); 228 } 229 case TimingFunction::CubicBezierFunction: { 230 const CubicBezierTimingFunction& cubic = toCubicBezierTimingFunction(lhs); 231 return (cubic == rhs); 232 } 233 case TimingFunction::StepsFunction: { 234 const StepsTimingFunction& step = toStepsTimingFunction(lhs); 235 return (step == rhs); 236 } 237 case TimingFunction::ChainedFunction: { 238 const ChainedTimingFunction& chained = toChainedTimingFunction(lhs); 239 return (chained == rhs); 240 } 241 default: 242 ASSERT_NOT_REACHED(); 243 } 244 return false; 245 } 246 247 // No need to define specific operator!= as they can all come via this function. 248 bool operator!=(const TimingFunction& lhs, const TimingFunction& rhs) 249 { 250 return !(lhs == rhs); 251 } 252 253 } // namespace WebCore 254