/// <summary> /// Walk the tree to determine the absolute start and end times of all the elements. /// the reference times passed in are absolute times, the result of calling this is to set the local start time /// and end time to absolute times between these two reference times, based on the begin, end and dur attributes /// and to recursively set all of the children. /// </summary> public void ComputeTimeIntervals(TimeContainer context, TimeCode referenceStart, TimeCode referenceEnd) { m_startTime = new TimeCode(0d, TimeExpression.CurrentSmpteFrameRate); m_endTime = new TimeCode(0d, TimeExpression.CurrentSmpteFrameRate); // compute the beginning of my interval. TimeCode begin = (Timing.ContainsKey("begin")) ? (TimeCode)Timing["begin"] : new TimeCode(0, TimeExpression.CurrentSmpteFrameRate); m_startTime = referenceStart + begin; TimeCode referenceDur, dur, end; // compute the simple duration of the interval , // par children have indefinite default duration, seq children have zero default duration. // (we dont support indefinite here but truncate to the outer container) // does end work here? surely it truncates the active duration, if (!Timing.ContainsKey("dur") && !Timing.ContainsKey("end") && context == TimeContainer.Seq) { referenceDur = new TimeCode(0, TimeExpression.CurrentSmpteFrameRate); } else { if (m_startTime < referenceEnd) { referenceDur = referenceEnd - m_startTime; } else { referenceDur = new TimeCode(0, TimeExpression.CurrentSmpteFrameRate); } } bool containsDur = false; if (Timing.ContainsKey("dur")) { containsDur = true; dur = (TimeCode)Timing["dur"]; if (dur > referenceDur) { dur = referenceDur; } } else { dur = referenceDur; } m_endTime = m_startTime + dur; // end can truncate the simple duration. TimeCode offsetEnd = new TimeCode(0, TimeExpression.CurrentSmpteFrameRate); offsetEnd += referenceStart; if (Timing.ContainsKey("end")) { end = referenceStart + ((TimeCode)Timing["end"]); } else { // Original code: // // end = referenceEnd; // // NOTE: This logic was changed from original TimedText library to properly handle // Sequential time containers when the duration is indefinite. if (context == TimeContainer.Par) { end = referenceEnd; } else { end = m_startTime + referenceDur; } } //end = (Timing.ContainsKey("end")) ? (m_startTime.Add((TimeSpan)Timing["end"])) : referenceEnd; if (!containsDur) { m_endTime = end; } else { m_endTime = (end < m_endTime) ? end : m_endTime; } if (TimeSemantics == TimeContainer.Par) { foreach (TimeTree <TChildren, TAttribute> child in m_children) { child.ComputeTimeIntervals(TimeSemantics, m_startTime, m_endTime); } } else { TimeCode s = m_startTime; foreach (TimeTree <TChildren, TAttribute> child in m_children) { child.ComputeTimeIntervals(TimeSemantics, s, m_endTime); s = child.m_endTime; } } }