Home | History | Annotate | Download | only in animation
      1 /*
      2  * Copyright (C) 2008 Apple 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
      6  * are met:
      7  * 1. Redistributions of source code must retain the above copyright
      8  *    notice, this list of conditions and the following disclaimer.
      9  * 2. Redistributions in binary form must reproduce the above copyright
     10  *    notice, this list of conditions and the following disclaimer in the
     11  *    documentation and/or other materials provided with the distribution.
     12  *
     13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
     14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
     17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
     20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
     21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     24  */
     25 
     26 #ifndef SMILTime_h
     27 #define SMILTime_h
     28 
     29 #include "wtf/Assertions.h"
     30 #include "wtf/HashTraits.h"
     31 #include "wtf/MathExtras.h"
     32 
     33 namespace blink {
     34 
     35 class SMILTime {
     36 public:
     37     SMILTime() : m_time(0) { }
     38     SMILTime(double time) : m_time(time) { }
     39 
     40     static SMILTime unresolved() { return std::numeric_limits<double>::quiet_NaN(); }
     41     static SMILTime indefinite() { return std::numeric_limits<double>::infinity(); }
     42 
     43     double value() const { return m_time; }
     44 
     45     bool isFinite() const { return std::isfinite(m_time); }
     46     bool isIndefinite() const { return std::isinf(m_time); }
     47     bool isUnresolved() const { return std::isnan(m_time); }
     48 
     49 private:
     50     double m_time;
     51 };
     52 
     53 class SMILTimeWithOrigin {
     54 public:
     55     enum Origin {
     56         ParserOrigin,
     57         ScriptOrigin
     58     };
     59 
     60     SMILTimeWithOrigin()
     61         : m_origin(ParserOrigin)
     62     {
     63     }
     64 
     65     SMILTimeWithOrigin(const SMILTime& time, Origin origin)
     66         : m_time(time)
     67         , m_origin(origin)
     68     {
     69     }
     70 
     71     const SMILTime& time() const { return m_time; }
     72     bool originIsScript() const { return m_origin == ScriptOrigin; }
     73 
     74 private:
     75     SMILTime m_time;
     76     Origin m_origin;
     77 };
     78 
     79 struct SMILInterval {
     80     SMILInterval() { }
     81     SMILInterval(const SMILTime& begin, const SMILTime& end) : begin(begin), end(end) { }
     82 
     83     SMILTime begin;
     84     SMILTime end;
     85 };
     86 
     87 inline bool operator==(const SMILTime& a, const SMILTime& b) { return (a.isUnresolved() && b.isUnresolved()) || a.value() == b.value(); }
     88 inline bool operator!(const SMILTime& a) { return !a.isFinite() || !a.value(); }
     89 inline bool operator!=(const SMILTime& a, const SMILTime& b) { return !operator==(a, b); }
     90 
     91 // Ordering of SMILTimes has to follow: finite < indefinite (Inf) < unresolved (NaN). The first comparison is handled by IEEE754 but
     92 // NaN values must be checked explicitly to guarantee that unresolved is ordered correctly too.
     93 inline bool operator>(const SMILTime& a, const SMILTime& b) { return a.isUnresolved() || (a.value() > b.value()); }
     94 inline bool operator<(const SMILTime& a, const SMILTime& b) { return operator>(b, a); }
     95 inline bool operator>=(const SMILTime& a, const SMILTime& b) { return operator>(a, b) || operator==(a, b); }
     96 inline bool operator<=(const SMILTime& a, const SMILTime& b) { return operator<(a, b) || operator==(a, b); }
     97 inline bool operator<(const SMILTimeWithOrigin& a, const SMILTimeWithOrigin& b) { return a.time() < b.time(); }
     98 
     99 inline SMILTime operator+(const SMILTime& a, const SMILTime& b) { return a.value() + b.value(); }
    100 inline SMILTime operator-(const SMILTime& a, const SMILTime& b) { return a.value() - b.value(); }
    101 // So multiplying times does not make too much sense but SMIL defines it for duration * repeatCount
    102 SMILTime operator*(const SMILTime&, const SMILTime&);
    103 
    104 inline bool operator!=(const SMILInterval& a, const SMILInterval& b)
    105 {
    106     // Compare the "raw" values since the operator!= for SMILTime always return
    107     // true for non-finite times.
    108     return a.begin.value() != b.begin.value() || a.end.value() != b.end.value();
    109 }
    110 
    111 struct SMILTimeHash {
    112     static unsigned hash(const SMILTime& key) { return WTF::FloatHash<double>::hash(key.value()); }
    113     static bool equal(const SMILTime& a, const SMILTime& b) { return WTF::FloatHash<double>::equal(a.value(), b.value()); }
    114     static const bool safeToCompareToEmptyOrDeleted = true;
    115 };
    116 
    117 } // namespace blink
    118 
    119 namespace WTF {
    120 
    121 template<> struct DefaultHash<blink::SMILTime> {
    122     typedef blink::SMILTimeHash Hash;
    123 };
    124 
    125 template<> struct HashTraits<blink::SMILTime> : GenericHashTraits<blink::SMILTime> {
    126     static blink::SMILTime emptyValue() { return blink::SMILTime::unresolved(); }
    127     static void constructDeletedValue(blink::SMILTime& slot, bool) { slot = -std::numeric_limits<double>::infinity(); }
    128     static bool isDeletedValue(blink::SMILTime value) { return value == -std::numeric_limits<double>::infinity(); }
    129 };
    130 
    131 } // namespace WTF
    132 
    133 #endif // SMILTime_h
    134