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 |