| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2008 Apple Inc. All rights reserved. | 2 * Copyright (C) 2008 Apple Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
| 6 * are met: | 6 * are met: |
| 7 * 1. Redistributions of source code must retain the above copyright | 7 * 1. Redistributions of source code must retain the above copyright |
| 8 * notice, this list of conditions and the following disclaimer. | 8 * notice, this list of conditions and the following disclaimer. |
| 9 * 2. Redistributions in binary form must reproduce the above copyright | 9 * 2. Redistributions in binary form must reproduce the above copyright |
| 10 * notice, this list of conditions and the following disclaimer in the | 10 * notice, this list of conditions and the following disclaimer in the |
| (...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 170 { | 170 { |
| 171 } | 171 } |
| 172 | 172 |
| 173 SVGSMILElement::SVGSMILElement(const QualifiedName& tagName, Document& doc) | 173 SVGSMILElement::SVGSMILElement(const QualifiedName& tagName, Document& doc) |
| 174 : SVGElement(tagName, doc) | 174 : SVGElement(tagName, doc) |
| 175 , m_attributeName(anyQName()) | 175 , m_attributeName(anyQName()) |
| 176 , m_targetElement(nullptr) | 176 , m_targetElement(nullptr) |
| 177 , m_syncBaseConditionsConnected(false) | 177 , m_syncBaseConditionsConnected(false) |
| 178 , m_hasEndEventConditions(false) | 178 , m_hasEndEventConditions(false) |
| 179 , m_isWaitingForFirstInterval(true) | 179 , m_isWaitingForFirstInterval(true) |
| 180 , m_intervalBegin(SMILTime::unresolved()) | 180 , m_interval(SMILInterval(SMILTime::unresolved(), SMILTime::unresolved())) |
| 181 , m_intervalEnd(SMILTime::unresolved()) | |
| 182 , m_previousIntervalBegin(SMILTime::unresolved()) | 181 , m_previousIntervalBegin(SMILTime::unresolved()) |
| 183 , m_activeState(Inactive) | 182 , m_activeState(Inactive) |
| 184 , m_lastPercent(0) | 183 , m_lastPercent(0) |
| 185 , m_lastRepeat(0) | 184 , m_lastRepeat(0) |
| 186 , m_nextProgressTime(0) | 185 , m_nextProgressTime(0) |
| 187 , m_documentOrderIndex(0) | 186 , m_documentOrderIndex(0) |
| 188 , m_cachedDur(invalidCachedTime) | 187 , m_cachedDur(invalidCachedTime) |
| 189 , m_cachedRepeatDur(invalidCachedTime) | 188 , m_cachedRepeatDur(invalidCachedTime) |
| 190 , m_cachedRepeatCount(invalidCachedTime) | 189 , m_cachedRepeatCount(invalidCachedTime) |
| 191 , m_cachedMin(invalidCachedTime) | 190 , m_cachedMin(invalidCachedTime) |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 292 timeList.remove(i); | 291 timeList.remove(i); |
| 293 } | 292 } |
| 294 } | 293 } |
| 295 | 294 |
| 296 void SVGSMILElement::reset() | 295 void SVGSMILElement::reset() |
| 297 { | 296 { |
| 298 clearAnimatedType(m_targetElement); | 297 clearAnimatedType(m_targetElement); |
| 299 | 298 |
| 300 m_activeState = Inactive; | 299 m_activeState = Inactive; |
| 301 m_isWaitingForFirstInterval = true; | 300 m_isWaitingForFirstInterval = true; |
| 302 m_intervalBegin = SMILTime::unresolved(); | 301 m_interval.begin = SMILTime::unresolved(); |
| 303 m_intervalEnd = SMILTime::unresolved(); | 302 m_interval.end = SMILTime::unresolved(); |
| 304 m_previousIntervalBegin = SMILTime::unresolved(); | 303 m_previousIntervalBegin = SMILTime::unresolved(); |
| 305 m_lastPercent = 0; | 304 m_lastPercent = 0; |
| 306 m_lastRepeat = 0; | 305 m_lastRepeat = 0; |
| 307 m_nextProgressTime = 0; | 306 m_nextProgressTime = 0; |
| 308 resolveFirstInterval(); | 307 resolveFirstInterval(); |
| 309 } | 308 } |
| 310 | 309 |
| 311 Node::InsertionNotificationRequest SVGSMILElement::insertedInto(ContainerNode* r
ootParent) | 310 Node::InsertionNotificationRequest SVGSMILElement::insertedInto(ContainerNode* r
ootParent) |
| 312 { | 311 { |
| 313 SVGElement::insertedInto(rootParent); | 312 SVGElement::insertedInto(rootParent); |
| (...skipping 578 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 892 // http://www.w3.org/TR/2001/REC-smil-animation-20010904/#MinMax | 891 // http://www.w3.org/TR/2001/REC-smil-animation-20010904/#MinMax |
| 893 minValue = 0; | 892 minValue = 0; |
| 894 maxValue = SMILTime::indefinite(); | 893 maxValue = SMILTime::indefinite(); |
| 895 } | 894 } |
| 896 return resolvedBegin + min(maxValue, max(minValue, preliminaryActiveDuration
)); | 895 return resolvedBegin + min(maxValue, max(minValue, preliminaryActiveDuration
)); |
| 897 } | 896 } |
| 898 | 897 |
| 899 void SVGSMILElement::resolveInterval(bool first, SMILTime& beginResult, SMILTime
& endResult) const | 898 void SVGSMILElement::resolveInterval(bool first, SMILTime& beginResult, SMILTime
& endResult) const |
| 900 { | 899 { |
| 901 // See the pseudocode in http://www.w3.org/TR/SMIL3/smil-timing.html#q90. | 900 // See the pseudocode in http://www.w3.org/TR/SMIL3/smil-timing.html#q90. |
| 902 SMILTime beginAfter = first ? -numeric_limits<double>::infinity() : m_interv
alEnd; | 901 SMILTime beginAfter = first ? -numeric_limits<double>::infinity() : m_interv
al.end; |
| 903 SMILTime lastIntervalTempEnd = numeric_limits<double>::infinity(); | 902 SMILTime lastIntervalTempEnd = numeric_limits<double>::infinity(); |
| 904 while (true) { | 903 while (true) { |
| 905 bool equalsMinimumOK = !first || m_intervalEnd > m_intervalBegin; | 904 bool equalsMinimumOK = !first || m_interval.end > m_interval.begin; |
| 906 SMILTime tempBegin = findInstanceTime(Begin, beginAfter, equalsMinimumOK
); | 905 SMILTime tempBegin = findInstanceTime(Begin, beginAfter, equalsMinimumOK
); |
| 907 if (tempBegin.isUnresolved()) | 906 if (tempBegin.isUnresolved()) |
| 908 break; | 907 break; |
| 909 SMILTime tempEnd; | 908 SMILTime tempEnd; |
| 910 if (m_endTimes.isEmpty()) | 909 if (m_endTimes.isEmpty()) |
| 911 tempEnd = resolveActiveEnd(tempBegin, SMILTime::indefinite()); | 910 tempEnd = resolveActiveEnd(tempBegin, SMILTime::indefinite()); |
| 912 else { | 911 else { |
| 913 tempEnd = findInstanceTime(End, tempBegin, true); | 912 tempEnd = findInstanceTime(End, tempBegin, true); |
| 914 if ((first && tempBegin == tempEnd && tempEnd == lastIntervalTempEnd
) || (!first && tempEnd == m_intervalEnd)) | 913 if ((first && tempBegin == tempEnd && tempEnd == lastIntervalTempEnd
) || (!first && tempEnd == m_interval.end)) |
| 915 tempEnd = findInstanceTime(End, tempBegin, false); | 914 tempEnd = findInstanceTime(End, tempBegin, false); |
| 916 if (tempEnd.isUnresolved()) { | 915 if (tempEnd.isUnresolved()) { |
| 917 if (!m_endTimes.isEmpty() && !m_hasEndEventConditions) | 916 if (!m_endTimes.isEmpty() && !m_hasEndEventConditions) |
| 918 break; | 917 break; |
| 919 } | 918 } |
| 920 tempEnd = resolveActiveEnd(tempBegin, tempEnd); | 919 tempEnd = resolveActiveEnd(tempBegin, tempEnd); |
| 921 } | 920 } |
| 922 if (!first || (tempEnd > 0 || (!tempBegin.value() && !tempEnd.value())))
{ | 921 if (!first || (tempEnd > 0 || (!tempBegin.value() && !tempEnd.value())))
{ |
| 923 beginResult = tempBegin; | 922 beginResult = tempBegin; |
| 924 endResult = tempEnd; | 923 endResult = tempEnd; |
| 925 return; | 924 return; |
| 926 } | 925 } |
| 927 | 926 |
| 928 beginAfter = tempEnd; | 927 beginAfter = tempEnd; |
| 929 lastIntervalTempEnd = tempEnd; | 928 lastIntervalTempEnd = tempEnd; |
| 930 } | 929 } |
| 931 beginResult = SMILTime::unresolved(); | 930 beginResult = SMILTime::unresolved(); |
| 932 endResult = SMILTime::unresolved(); | 931 endResult = SMILTime::unresolved(); |
| 933 } | 932 } |
| 934 | 933 |
| 935 void SVGSMILElement::resolveFirstInterval() | 934 void SVGSMILElement::resolveFirstInterval() |
| 936 { | 935 { |
| 937 SMILInterval firstInterval; | 936 SMILInterval firstInterval; |
| 938 resolveInterval(true, firstInterval.begin, firstInterval.end); | 937 resolveInterval(true, firstInterval.begin, firstInterval.end); |
| 939 ASSERT(!firstInterval.begin.isIndefinite()); | 938 ASSERT(!firstInterval.begin.isIndefinite()); |
| 940 | 939 |
| 941 if (!firstInterval.begin.isUnresolved() && firstInterval != SMILInterval(m_i
ntervalBegin, m_intervalEnd)) { | 940 if (!firstInterval.begin.isUnresolved() && firstInterval != SMILInterval(m_i
nterval.begin, m_interval.end)) { |
| 942 m_intervalBegin = firstInterval.begin; | 941 m_interval.begin = firstInterval.begin; |
| 943 m_intervalEnd = firstInterval.end; | 942 m_interval.end = firstInterval.end; |
| 944 notifyDependentsIntervalChanged(); | 943 notifyDependentsIntervalChanged(); |
| 945 m_nextProgressTime = min(m_nextProgressTime, m_intervalBegin); | 944 m_nextProgressTime = min(m_nextProgressTime, m_interval.begin); |
| 946 | 945 |
| 947 if (m_timeContainer) | 946 if (m_timeContainer) |
| 948 m_timeContainer->notifyIntervalsChanged(); | 947 m_timeContainer->notifyIntervalsChanged(); |
| 949 } | 948 } |
| 950 } | 949 } |
| 951 | 950 |
| 952 bool SVGSMILElement::resolveNextInterval() | 951 bool SVGSMILElement::resolveNextInterval() |
| 953 { | 952 { |
| 954 SMILTime begin; | 953 SMILTime begin; |
| 955 SMILTime end; | 954 SMILTime end; |
| 956 resolveInterval(false, begin, end); | 955 resolveInterval(false, begin, end); |
| 957 ASSERT(!begin.isIndefinite()); | 956 ASSERT(!begin.isIndefinite()); |
| 958 | 957 |
| 959 if (!begin.isUnresolved() && begin != m_intervalBegin) { | 958 if (!begin.isUnresolved() && begin != m_interval.begin) { |
| 960 m_intervalBegin = begin; | 959 m_interval.begin = begin; |
| 961 m_intervalEnd = end; | 960 m_interval.end = end; |
| 962 notifyDependentsIntervalChanged(); | 961 notifyDependentsIntervalChanged(); |
| 963 m_nextProgressTime = min(m_nextProgressTime, m_intervalBegin); | 962 m_nextProgressTime = min(m_nextProgressTime, m_interval.begin); |
| 964 return true; | 963 return true; |
| 965 } | 964 } |
| 966 | 965 |
| 967 return false; | 966 return false; |
| 968 } | 967 } |
| 969 | 968 |
| 970 SMILTime SVGSMILElement::nextProgressTime() const | 969 SMILTime SVGSMILElement::nextProgressTime() const |
| 971 { | 970 { |
| 972 return m_nextProgressTime; | 971 return m_nextProgressTime; |
| 973 } | 972 } |
| 974 | 973 |
| 975 void SVGSMILElement::beginListChanged(SMILTime eventTime) | 974 void SVGSMILElement::beginListChanged(SMILTime eventTime) |
| 976 { | 975 { |
| 977 if (m_isWaitingForFirstInterval) | 976 if (m_isWaitingForFirstInterval) |
| 978 resolveFirstInterval(); | 977 resolveFirstInterval(); |
| 979 else { | 978 else { |
| 980 SMILTime newBegin = findInstanceTime(Begin, eventTime, true); | 979 SMILTime newBegin = findInstanceTime(Begin, eventTime, true); |
| 981 if (newBegin.isFinite() && (m_intervalEnd <= eventTime || newBegin < m_i
ntervalBegin)) { | 980 if (newBegin.isFinite() && (m_interval.end <= eventTime || newBegin < m_
interval.begin)) { |
| 982 // Begin time changed, re-resolve the interval. | 981 // Begin time changed, re-resolve the interval. |
| 983 SMILTime oldBegin = m_intervalBegin; | 982 SMILTime oldBegin = m_interval.begin; |
| 984 m_intervalEnd = eventTime; | 983 m_interval.end = eventTime; |
| 985 resolveInterval(false, m_intervalBegin, m_intervalEnd); | 984 resolveInterval(false, m_interval.begin, m_interval.end); |
| 986 ASSERT(!m_intervalBegin.isUnresolved()); | 985 ASSERT(!m_interval.begin.isUnresolved()); |
| 987 if (m_intervalBegin != oldBegin) { | 986 if (m_interval.begin != oldBegin) { |
| 988 if (m_activeState == Active && m_intervalBegin > eventTime) { | 987 if (m_activeState == Active && m_interval.begin > eventTime) { |
| 989 m_activeState = determineActiveState(eventTime); | 988 m_activeState = determineActiveState(eventTime); |
| 990 if (m_activeState != Active) | 989 if (m_activeState != Active) |
| 991 endedActiveInterval(); | 990 endedActiveInterval(); |
| 992 } | 991 } |
| 993 notifyDependentsIntervalChanged(); | 992 notifyDependentsIntervalChanged(); |
| 994 } | 993 } |
| 995 } | 994 } |
| 996 } | 995 } |
| 997 m_nextProgressTime = elapsed(); | 996 m_nextProgressTime = elapsed(); |
| 998 | 997 |
| 999 if (m_timeContainer) | 998 if (m_timeContainer) |
| 1000 m_timeContainer->notifyIntervalsChanged(); | 999 m_timeContainer->notifyIntervalsChanged(); |
| 1001 } | 1000 } |
| 1002 | 1001 |
| 1003 void SVGSMILElement::endListChanged(SMILTime) | 1002 void SVGSMILElement::endListChanged(SMILTime) |
| 1004 { | 1003 { |
| 1005 SMILTime elapsed = this->elapsed(); | 1004 SMILTime elapsed = this->elapsed(); |
| 1006 if (m_isWaitingForFirstInterval) | 1005 if (m_isWaitingForFirstInterval) { |
| 1007 resolveFirstInterval(); | 1006 resolveFirstInterval(); |
| 1008 else if (elapsed < m_intervalEnd && m_intervalBegin.isFinite()) { | 1007 } else if (elapsed < m_interval.end && m_interval.begin.isFinite()) { |
| 1009 SMILTime newEnd = findInstanceTime(End, m_intervalBegin, false); | 1008 SMILTime newEnd = findInstanceTime(End, m_interval.begin, false); |
| 1010 if (newEnd < m_intervalEnd) { | 1009 if (newEnd < m_interval.end) { |
| 1011 newEnd = resolveActiveEnd(m_intervalBegin, newEnd); | 1010 newEnd = resolveActiveEnd(m_interval.begin, newEnd); |
| 1012 if (newEnd != m_intervalEnd) { | 1011 if (newEnd != m_interval.end) { |
| 1013 m_intervalEnd = newEnd; | 1012 m_interval.end = newEnd; |
| 1014 notifyDependentsIntervalChanged(); | 1013 notifyDependentsIntervalChanged(); |
| 1015 } | 1014 } |
| 1016 } | 1015 } |
| 1017 } | 1016 } |
| 1018 m_nextProgressTime = elapsed; | 1017 m_nextProgressTime = elapsed; |
| 1019 | 1018 |
| 1020 if (m_timeContainer) | 1019 if (m_timeContainer) |
| 1021 m_timeContainer->notifyIntervalsChanged(); | 1020 m_timeContainer->notifyIntervalsChanged(); |
| 1022 } | 1021 } |
| 1023 | 1022 |
| 1024 SVGSMILElement::RestartedInterval SVGSMILElement::maybeRestartInterval(SMILTime
elapsed) | 1023 SVGSMILElement::RestartedInterval SVGSMILElement::maybeRestartInterval(SMILTime
elapsed) |
| 1025 { | 1024 { |
| 1026 ASSERT(!m_isWaitingForFirstInterval); | 1025 ASSERT(!m_isWaitingForFirstInterval); |
| 1027 ASSERT(elapsed >= m_intervalBegin); | 1026 ASSERT(elapsed >= m_interval.begin); |
| 1028 | 1027 |
| 1029 Restart restart = this->restart(); | 1028 Restart restart = this->restart(); |
| 1030 if (restart == RestartNever) | 1029 if (restart == RestartNever) |
| 1031 return DidNotRestartInterval; | 1030 return DidNotRestartInterval; |
| 1032 | 1031 |
| 1033 if (elapsed < m_intervalEnd) { | 1032 if (elapsed < m_interval.end) { |
| 1034 if (restart != RestartAlways) | 1033 if (restart != RestartAlways) |
| 1035 return DidNotRestartInterval; | 1034 return DidNotRestartInterval; |
| 1036 SMILTime nextBegin = findInstanceTime(Begin, m_intervalBegin, false); | 1035 SMILTime nextBegin = findInstanceTime(Begin, m_interval.begin, false); |
| 1037 if (nextBegin < m_intervalEnd) { | 1036 if (nextBegin < m_interval.end) { |
| 1038 m_intervalEnd = nextBegin; | 1037 m_interval.end = nextBegin; |
| 1039 notifyDependentsIntervalChanged(); | 1038 notifyDependentsIntervalChanged(); |
| 1040 } | 1039 } |
| 1041 } | 1040 } |
| 1042 | 1041 |
| 1043 if (elapsed >= m_intervalEnd) { | 1042 if (elapsed >= m_interval.end) { |
| 1044 if (resolveNextInterval() && elapsed >= m_intervalBegin) | 1043 if (resolveNextInterval() && elapsed >= m_interval.begin) |
| 1045 return DidRestartInterval; | 1044 return DidRestartInterval; |
| 1046 } | 1045 } |
| 1047 return DidNotRestartInterval; | 1046 return DidNotRestartInterval; |
| 1048 } | 1047 } |
| 1049 | 1048 |
| 1050 void SVGSMILElement::seekToIntervalCorrespondingToTime(SMILTime elapsed) | 1049 void SVGSMILElement::seekToIntervalCorrespondingToTime(SMILTime elapsed) |
| 1051 { | 1050 { |
| 1052 ASSERT(!m_isWaitingForFirstInterval); | 1051 ASSERT(!m_isWaitingForFirstInterval); |
| 1053 ASSERT(elapsed >= m_intervalBegin); | 1052 ASSERT(elapsed >= m_interval.begin); |
| 1054 | 1053 |
| 1055 // Manually seek from interval to interval, just as if the animation would r
un regulary. | 1054 // Manually seek from interval to interval, just as if the animation would r
un regulary. |
| 1056 while (true) { | 1055 while (true) { |
| 1057 // Figure out the next value in the begin time list after the current in
terval begin. | 1056 // Figure out the next value in the begin time list after the current in
terval begin. |
| 1058 SMILTime nextBegin = findInstanceTime(Begin, m_intervalBegin, false); | 1057 SMILTime nextBegin = findInstanceTime(Begin, m_interval.begin, false); |
| 1059 | 1058 |
| 1060 // If the 'nextBegin' time is unresolved (eg. just one defined interval)
, we're done seeking. | 1059 // If the 'nextBegin' time is unresolved (eg. just one defined interval)
, we're done seeking. |
| 1061 if (nextBegin.isUnresolved()) | 1060 if (nextBegin.isUnresolved()) |
| 1062 return; | 1061 return; |
| 1063 | 1062 |
| 1064 // If the 'nextBegin' time is larger than or equal to the current interv
al end time, we're done seeking. | 1063 // If the 'nextBegin' time is larger than or equal to the current interv
al end time, we're done seeking. |
| 1065 // If the 'elapsed' time is smaller than the next begin interval time, w
e're done seeking. | 1064 // If the 'elapsed' time is smaller than the next begin interval time, w
e're done seeking. |
| 1066 if (nextBegin < m_intervalEnd && elapsed >= nextBegin) { | 1065 if (nextBegin < m_interval.end && elapsed >= nextBegin) { |
| 1067 // End current interval, and start a new interval from the 'nextBegi
n' time. | 1066 // End current interval, and start a new interval from the 'nextBegi
n' time. |
| 1068 m_intervalEnd = nextBegin; | 1067 m_interval.end = nextBegin; |
| 1069 if (!resolveNextInterval()) | 1068 if (!resolveNextInterval()) |
| 1070 break; | 1069 break; |
| 1071 continue; | 1070 continue; |
| 1072 } | 1071 } |
| 1073 | 1072 |
| 1074 // If the desired 'elapsed' time is past the current interval, advance t
o the next. | 1073 // If the desired 'elapsed' time is past the current interval, advance t
o the next. |
| 1075 if (elapsed >= m_intervalEnd) { | 1074 if (elapsed >= m_interval.end) { |
| 1076 if (!resolveNextInterval()) | 1075 if (!resolveNextInterval()) |
| 1077 break; | 1076 break; |
| 1078 continue; | 1077 continue; |
| 1079 } | 1078 } |
| 1080 | 1079 |
| 1081 return; | 1080 return; |
| 1082 } | 1081 } |
| 1083 } | 1082 } |
| 1084 | 1083 |
| 1085 float SVGSMILElement::calculateAnimationPercentAndRepeat(SMILTime elapsed, unsig
ned& repeat) const | 1084 float SVGSMILElement::calculateAnimationPercentAndRepeat(SMILTime elapsed, unsig
ned& repeat) const |
| 1086 { | 1085 { |
| 1087 SMILTime simpleDuration = this->simpleDuration(); | 1086 SMILTime simpleDuration = this->simpleDuration(); |
| 1088 repeat = 0; | 1087 repeat = 0; |
| 1089 if (simpleDuration.isIndefinite()) { | 1088 if (simpleDuration.isIndefinite()) { |
| 1090 repeat = 0; | 1089 repeat = 0; |
| 1091 return 0.f; | 1090 return 0.f; |
| 1092 } | 1091 } |
| 1093 if (!simpleDuration) { | 1092 if (!simpleDuration) { |
| 1094 repeat = 0; | 1093 repeat = 0; |
| 1095 return 1.f; | 1094 return 1.f; |
| 1096 } | 1095 } |
| 1097 ASSERT(m_intervalBegin.isFinite()); | 1096 ASSERT(m_interval.begin.isFinite()); |
| 1098 ASSERT(simpleDuration.isFinite()); | 1097 ASSERT(simpleDuration.isFinite()); |
| 1099 SMILTime activeTime = elapsed - m_intervalBegin; | 1098 SMILTime activeTime = elapsed - m_interval.begin; |
| 1100 SMILTime repeatingDuration = this->repeatingDuration(); | 1099 SMILTime repeatingDuration = this->repeatingDuration(); |
| 1101 if (elapsed >= m_intervalEnd || activeTime > repeatingDuration) { | 1100 if (elapsed >= m_interval.end || activeTime > repeatingDuration) { |
| 1102 repeat = static_cast<unsigned>(repeatingDuration.value() / simpleDuratio
n.value()); | 1101 repeat = static_cast<unsigned>(repeatingDuration.value() / simpleDuratio
n.value()); |
| 1103 if (!fmod(repeatingDuration.value(), simpleDuration.value())) | 1102 if (!fmod(repeatingDuration.value(), simpleDuration.value())) |
| 1104 repeat--; | 1103 repeat--; |
| 1105 | 1104 |
| 1106 double percent = (m_intervalEnd.value() - m_intervalBegin.value()) / sim
pleDuration.value(); | 1105 double percent = (m_interval.end.value() - m_interval.begin.value()) / s
impleDuration.value(); |
| 1107 percent = percent - floor(percent); | 1106 percent = percent - floor(percent); |
| 1108 if (percent < numeric_limits<float>::epsilon() || 1 - percent < numeric_
limits<float>::epsilon()) | 1107 if (percent < numeric_limits<float>::epsilon() || 1 - percent < numeric_
limits<float>::epsilon()) |
| 1109 return 1.0f; | 1108 return 1.0f; |
| 1110 return narrowPrecisionToFloat(percent); | 1109 return narrowPrecisionToFloat(percent); |
| 1111 } | 1110 } |
| 1112 repeat = static_cast<unsigned>(activeTime.value() / simpleDuration.value()); | 1111 repeat = static_cast<unsigned>(activeTime.value() / simpleDuration.value()); |
| 1113 SMILTime simpleTime = fmod(activeTime.value(), simpleDuration.value()); | 1112 SMILTime simpleTime = fmod(activeTime.value(), simpleDuration.value()); |
| 1114 return narrowPrecisionToFloat(simpleTime.value() / simpleDuration.value()); | 1113 return narrowPrecisionToFloat(simpleTime.value() / simpleDuration.value()); |
| 1115 } | 1114 } |
| 1116 | 1115 |
| 1117 SMILTime SVGSMILElement::calculateNextProgressTime(SMILTime elapsed) const | 1116 SMILTime SVGSMILElement::calculateNextProgressTime(SMILTime elapsed) const |
| 1118 { | 1117 { |
| 1119 if (m_activeState == Active) { | 1118 if (m_activeState == Active) { |
| 1120 // If duration is indefinite the value does not actually change over tim
e. Same is true for <set>. | 1119 // If duration is indefinite the value does not actually change over tim
e. Same is true for <set>. |
| 1121 SMILTime simpleDuration = this->simpleDuration(); | 1120 SMILTime simpleDuration = this->simpleDuration(); |
| 1122 if (simpleDuration.isIndefinite() || isSVGSetElement(*this)) { | 1121 if (simpleDuration.isIndefinite() || isSVGSetElement(*this)) { |
| 1123 SMILTime repeatingDurationEnd = m_intervalBegin + repeatingDuration(
); | 1122 SMILTime repeatingDurationEnd = m_interval.begin + repeatingDuration
(); |
| 1124 // We are supposed to do freeze semantics when repeating ends, even
if the element is still active. | 1123 // We are supposed to do freeze semantics when repeating ends, even
if the element is still active. |
| 1125 // Take care that we get a timer callback at that point. | 1124 // Take care that we get a timer callback at that point. |
| 1126 if (elapsed < repeatingDurationEnd && repeatingDurationEnd < m_inter
valEnd && repeatingDurationEnd.isFinite()) | 1125 if (elapsed < repeatingDurationEnd && repeatingDurationEnd < m_inter
val.end && repeatingDurationEnd.isFinite()) |
| 1127 return repeatingDurationEnd; | 1126 return repeatingDurationEnd; |
| 1128 return m_intervalEnd; | 1127 return m_interval.end; |
| 1129 } | 1128 } |
| 1130 return elapsed + 0.025; | 1129 return elapsed + 0.025; |
| 1131 } | 1130 } |
| 1132 return m_intervalBegin >= elapsed ? m_intervalBegin : SMILTime::unresolved()
; | 1131 return m_interval.begin >= elapsed ? m_interval.begin : SMILTime::unresolved
(); |
| 1133 } | 1132 } |
| 1134 | 1133 |
| 1135 SVGSMILElement::ActiveState SVGSMILElement::determineActiveState(SMILTime elapse
d) const | 1134 SVGSMILElement::ActiveState SVGSMILElement::determineActiveState(SMILTime elapse
d) const |
| 1136 { | 1135 { |
| 1137 if (elapsed >= m_intervalBegin && elapsed < m_intervalEnd) | 1136 if (elapsed >= m_interval.begin && elapsed < m_interval.end) |
| 1138 return Active; | 1137 return Active; |
| 1139 | 1138 |
| 1140 return fill() == FillFreeze ? Frozen : Inactive; | 1139 return fill() == FillFreeze ? Frozen : Inactive; |
| 1141 } | 1140 } |
| 1142 | 1141 |
| 1143 bool SVGSMILElement::isContributing(SMILTime elapsed) const | 1142 bool SVGSMILElement::isContributing(SMILTime elapsed) const |
| 1144 { | 1143 { |
| 1145 // Animation does not contribute during the active time if it is past its re
peating duration and has fill=remove. | 1144 // Animation does not contribute during the active time if it is past its re
peating duration and has fill=remove. |
| 1146 return (m_activeState == Active && (fill() == FillFreeze || elapsed <= m_int
ervalBegin + repeatingDuration())) || m_activeState == Frozen; | 1145 return (m_activeState == Active && (fill() == FillFreeze || elapsed <= m_int
erval.begin + repeatingDuration())) || m_activeState == Frozen; |
| 1147 } | 1146 } |
| 1148 | 1147 |
| 1149 bool SVGSMILElement::progress(SMILTime elapsed, SVGSMILElement* resultElement, b
ool seekToTime) | 1148 bool SVGSMILElement::progress(SMILTime elapsed, SVGSMILElement* resultElement, b
ool seekToTime) |
| 1150 { | 1149 { |
| 1151 ASSERT(resultElement); | 1150 ASSERT(resultElement); |
| 1152 ASSERT(m_timeContainer); | 1151 ASSERT(m_timeContainer); |
| 1153 ASSERT(m_isWaitingForFirstInterval || m_intervalBegin.isFinite()); | 1152 ASSERT(m_isWaitingForFirstInterval || m_interval.begin.isFinite()); |
| 1154 | 1153 |
| 1155 if (!m_syncBaseConditionsConnected) | 1154 if (!m_syncBaseConditionsConnected) |
| 1156 connectSyncBaseConditions(); | 1155 connectSyncBaseConditions(); |
| 1157 | 1156 |
| 1158 if (!m_intervalBegin.isFinite()) { | 1157 if (!m_interval.begin.isFinite()) { |
| 1159 ASSERT(m_activeState == Inactive); | 1158 ASSERT(m_activeState == Inactive); |
| 1160 m_nextProgressTime = SMILTime::unresolved(); | 1159 m_nextProgressTime = SMILTime::unresolved(); |
| 1161 return false; | 1160 return false; |
| 1162 } | 1161 } |
| 1163 | 1162 |
| 1164 if (elapsed < m_intervalBegin) { | 1163 if (elapsed < m_interval.begin) { |
| 1165 ASSERT(m_activeState != Active); | 1164 ASSERT(m_activeState != Active); |
| 1166 if (m_activeState == Frozen) { | 1165 if (m_activeState == Frozen) { |
| 1167 if (this == resultElement) | 1166 if (this == resultElement) |
| 1168 resetAnimatedType(); | 1167 resetAnimatedType(); |
| 1169 updateAnimation(m_lastPercent, m_lastRepeat, resultElement); | 1168 updateAnimation(m_lastPercent, m_lastRepeat, resultElement); |
| 1170 } | 1169 } |
| 1171 m_nextProgressTime = m_intervalBegin; | 1170 m_nextProgressTime = m_interval.begin; |
| 1172 return false; | 1171 return false; |
| 1173 } | 1172 } |
| 1174 | 1173 |
| 1175 m_previousIntervalBegin = m_intervalBegin; | 1174 m_previousIntervalBegin = m_interval.begin; |
| 1176 | 1175 |
| 1177 if (m_isWaitingForFirstInterval) { | 1176 if (m_isWaitingForFirstInterval) { |
| 1178 m_isWaitingForFirstInterval = false; | 1177 m_isWaitingForFirstInterval = false; |
| 1179 resolveFirstInterval(); | 1178 resolveFirstInterval(); |
| 1180 } | 1179 } |
| 1181 | 1180 |
| 1182 // This call may obtain a new interval -- never call calculateAnimationPerce
ntAndRepeat() before! | 1181 // This call may obtain a new interval -- never call calculateAnimationPerce
ntAndRepeat() before! |
| 1183 if (seekToTime) { | 1182 if (seekToTime) { |
| 1184 seekToIntervalCorrespondingToTime(elapsed); | 1183 seekToIntervalCorrespondingToTime(elapsed); |
| 1185 if (elapsed < m_intervalBegin) { | 1184 if (elapsed < m_interval.begin) { |
| 1186 // elapsed is not within an interval. | 1185 // elapsed is not within an interval. |
| 1187 m_nextProgressTime = m_intervalBegin; | 1186 m_nextProgressTime = m_interval.begin; |
| 1188 return false; | 1187 return false; |
| 1189 } | 1188 } |
| 1190 } | 1189 } |
| 1191 | 1190 |
| 1192 unsigned repeat = 0; | 1191 unsigned repeat = 0; |
| 1193 float percent = calculateAnimationPercentAndRepeat(elapsed, repeat); | 1192 float percent = calculateAnimationPercentAndRepeat(elapsed, repeat); |
| 1194 RestartedInterval restartedInterval = maybeRestartInterval(elapsed); | 1193 RestartedInterval restartedInterval = maybeRestartInterval(elapsed); |
| 1195 | 1194 |
| 1196 ActiveState oldActiveState = m_activeState; | 1195 ActiveState oldActiveState = m_activeState; |
| 1197 m_activeState = determineActiveState(elapsed); | 1196 m_activeState = determineActiveState(elapsed); |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1237 if (m_activeState == Inactive || m_activeState == Frozen) | 1236 if (m_activeState == Inactive || m_activeState == Frozen) |
| 1238 smilEndEventSender().dispatchEventSoon(this); | 1237 smilEndEventSender().dispatchEventSoon(this); |
| 1239 } | 1238 } |
| 1240 | 1239 |
| 1241 m_nextProgressTime = calculateNextProgressTime(elapsed); | 1240 m_nextProgressTime = calculateNextProgressTime(elapsed); |
| 1242 return animationIsContributing; | 1241 return animationIsContributing; |
| 1243 } | 1242 } |
| 1244 | 1243 |
| 1245 void SVGSMILElement::notifyDependentsIntervalChanged() | 1244 void SVGSMILElement::notifyDependentsIntervalChanged() |
| 1246 { | 1245 { |
| 1247 ASSERT(m_intervalBegin.isFinite()); | 1246 ASSERT(m_interval.begin.isFinite()); |
| 1248 // |loopBreaker| is used to avoid infinite recursions which may be caused fr
om: | 1247 // |loopBreaker| is used to avoid infinite recursions which may be caused fr
om: |
| 1249 // |notifyDependentsIntervalChanged| -> |createInstanceTimesFromSyncbase| ->
|add{Begin,End}Time| -> |{begin,end}TimeChanged| -> |notifyDependentsIntervalCh
anged| | 1248 // |notifyDependentsIntervalChanged| -> |createInstanceTimesFromSyncbase| ->
|add{Begin,End}Time| -> |{begin,end}TimeChanged| -> |notifyDependentsIntervalCh
anged| |
| 1250 // |loopBreaker| is defined as a Persistent<HeapHashSet<Member<SVGSMILElemen
t> > >. This won't cause leaks because it is guaranteed to be empty after the ro
ot |notifyDependentsIntervalChanged| has exited. | 1249 // |loopBreaker| is defined as a Persistent<HeapHashSet<Member<SVGSMILElemen
t> > >. This won't cause leaks because it is guaranteed to be empty after the ro
ot |notifyDependentsIntervalChanged| has exited. |
| 1251 DEFINE_STATIC_LOCAL(OwnPtrWillBePersistent<WillBeHeapHashSet<RawPtrWillBeMem
ber<SVGSMILElement> > >, loopBreaker, (adoptPtrWillBeNoop(new WillBeHeapHashSet<
RawPtrWillBeMember<SVGSMILElement> >()))); | 1250 DEFINE_STATIC_LOCAL(OwnPtrWillBePersistent<WillBeHeapHashSet<RawPtrWillBeMem
ber<SVGSMILElement> > >, loopBreaker, (adoptPtrWillBeNoop(new WillBeHeapHashSet<
RawPtrWillBeMember<SVGSMILElement> >()))); |
| 1252 if (!loopBreaker->add(this).isNewEntry) | 1251 if (!loopBreaker->add(this).isNewEntry) |
| 1253 return; | 1252 return; |
| 1254 | 1253 |
| 1255 TimeDependentSet::iterator end = m_syncBaseDependents.end(); | 1254 TimeDependentSet::iterator end = m_syncBaseDependents.end(); |
| 1256 for (TimeDependentSet::iterator it = m_syncBaseDependents.begin(); it != end
; ++it) { | 1255 for (TimeDependentSet::iterator it = m_syncBaseDependents.begin(); it != end
; ++it) { |
| 1257 SVGSMILElement* dependent = *it; | 1256 SVGSMILElement* dependent = *it; |
| 1258 dependent->createInstanceTimesFromSyncbase(this); | 1257 dependent->createInstanceTimesFromSyncbase(this); |
| 1259 } | 1258 } |
| 1260 | 1259 |
| 1261 loopBreaker->remove(this); | 1260 loopBreaker->remove(this); |
| 1262 } | 1261 } |
| 1263 | 1262 |
| 1264 void SVGSMILElement::createInstanceTimesFromSyncbase(SVGSMILElement* syncBase) | 1263 void SVGSMILElement::createInstanceTimesFromSyncbase(SVGSMILElement* syncBase) |
| 1265 { | 1264 { |
| 1266 // FIXME: To be really correct, this should handle updating exising interval
by changing | 1265 // FIXME: To be really correct, this should handle updating exising interval
by changing |
| 1267 // the associated times instead of creating new ones. | 1266 // the associated times instead of creating new ones. |
| 1268 for (unsigned n = 0; n < m_conditions.size(); ++n) { | 1267 for (unsigned n = 0; n < m_conditions.size(); ++n) { |
| 1269 Condition* condition = m_conditions[n].get(); | 1268 Condition* condition = m_conditions[n].get(); |
| 1270 if (condition->type() == Condition::Syncbase && condition->syncBase() ==
syncBase) { | 1269 if (condition->type() == Condition::Syncbase && condition->syncBase() ==
syncBase) { |
| 1271 ASSERT(condition->name() == "begin" || condition->name() == "end"); | 1270 ASSERT(condition->name() == "begin" || condition->name() == "end"); |
| 1272 // No nested time containers in SVG, no need for crazy time space co
nversions. Phew! | 1271 // No nested time containers in SVG, no need for crazy time space co
nversions. Phew! |
| 1273 SMILTime time = 0; | 1272 SMILTime time = 0; |
| 1274 if (condition->name() == "begin") | 1273 if (condition->name() == "begin") |
| 1275 time = syncBase->m_intervalBegin + condition->offset(); | 1274 time = syncBase->m_interval.begin + condition->offset(); |
| 1276 else | 1275 else |
| 1277 time = syncBase->m_intervalEnd + condition->offset(); | 1276 time = syncBase->m_interval.end + condition->offset(); |
| 1278 if (!time.isFinite()) | 1277 if (!time.isFinite()) |
| 1279 continue; | 1278 continue; |
| 1280 if (condition->beginOrEnd() == Begin) | 1279 if (condition->beginOrEnd() == Begin) |
| 1281 addBeginTime(elapsed(), time); | 1280 addBeginTime(elapsed(), time); |
| 1282 else | 1281 else |
| 1283 addEndTime(elapsed(), time); | 1282 addEndTime(elapsed(), time); |
| 1284 } | 1283 } |
| 1285 } | 1284 } |
| 1286 } | 1285 } |
| 1287 | 1286 |
| 1288 void SVGSMILElement::addSyncBaseDependent(SVGSMILElement* animation) | 1287 void SVGSMILElement::addSyncBaseDependent(SVGSMILElement* animation) |
| 1289 { | 1288 { |
| 1290 m_syncBaseDependents.add(animation); | 1289 m_syncBaseDependents.add(animation); |
| 1291 if (m_intervalBegin.isFinite()) | 1290 if (m_interval.begin.isFinite()) |
| 1292 animation->createInstanceTimesFromSyncbase(this); | 1291 animation->createInstanceTimesFromSyncbase(this); |
| 1293 } | 1292 } |
| 1294 | 1293 |
| 1295 void SVGSMILElement::removeSyncBaseDependent(SVGSMILElement* animation) | 1294 void SVGSMILElement::removeSyncBaseDependent(SVGSMILElement* animation) |
| 1296 { | 1295 { |
| 1297 m_syncBaseDependents.remove(animation); | 1296 m_syncBaseDependents.remove(animation); |
| 1298 } | 1297 } |
| 1299 | 1298 |
| 1300 void SVGSMILElement::handleConditionEvent(Event* event, Condition* condition) | 1299 void SVGSMILElement::handleConditionEvent(Event* event, Condition* condition) |
| 1301 { | 1300 { |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1353 void SVGSMILElement::trace(Visitor* visitor) | 1352 void SVGSMILElement::trace(Visitor* visitor) |
| 1354 { | 1353 { |
| 1355 visitor->trace(m_targetElement); | 1354 visitor->trace(m_targetElement); |
| 1356 visitor->trace(m_timeContainer); | 1355 visitor->trace(m_timeContainer); |
| 1357 visitor->trace(m_conditions); | 1356 visitor->trace(m_conditions); |
| 1358 visitor->trace(m_syncBaseDependents); | 1357 visitor->trace(m_syncBaseDependents); |
| 1359 SVGElement::trace(visitor); | 1358 SVGElement::trace(visitor); |
| 1360 } | 1359 } |
| 1361 | 1360 |
| 1362 } | 1361 } |
| OLD | NEW |