📄 smlparse.cpp
字号:
// /See if above replaces this code; if no assert reported by
// 2001-05-20, then I'm going to remove this whole if() block:
HX_ASSERT(0 && "mailto: ehodge@real.com");
goto cleanup; //Don't insert this because it can't ever play.
}
// /Also, need to check parent *dur* and make sure we don't
// exceed it if it's been explicitly set to a finite amount:
if ( pNode->m_pParent && pNode->m_pParent->m_pElement &&
pNode->m_pElement->m_bBeginOffsetSet &&
pNode->m_pParent->m_pElement->m_bHasExplicitDur &&
!pNode->m_pParent->m_pElement->m_bIndefiniteDuration &&
(pNode->m_pElement->m_lBeginOffset > 0 &&
(UINT32)pNode->m_pElement->m_lBeginOffset >
pNode->m_pParent->m_pElement->m_ulDuration) )
{
// /See if above replaces this code; if no assert reported by
// 2001-05-20, then I'm going to remove this whole if() block:
HX_ASSERT(0 && "mailto: ehodge@real.com");
goto cleanup; //Don't insert this because it can't ever play.
}
#endif
// If this element uses media markers for clipBegin
// then those markers need to be resolved
if (pNode->m_pElement->m_bClipBeginUsesMarker &&
!pNode->m_pElement->m_bClipBeginMarkerResolved)
{
// Set the flag saying we WOULD have scheduled
// this element except the clip begin marker wasn't
// resolved yet.
pNode->m_pElement->m_bWaitingOnClipBeginToResolve = TRUE;
goto cleanup; // don't insert cause we don't know the clipBegin yet
}
// If this element uses media markers for clipEnd
// then those markers need to be resolved
if (pNode->m_pElement->m_bClipEndUsesMarker &&
!pNode->m_pElement->m_bClipEndMarkerResolved)
{
// Set the flag saying we WOULD have scheduled
// this element except the clip end marker wasn't
// resolved yet.
pNode->m_pElement->m_bWaitingOnClipEndToResolve = TRUE;
goto cleanup; // don't insert cause we don't know the clipEnd yet
}
// skip the element if its duration == 0
if (0 == pNode->m_pElement->m_ulDuration)
{
durationResolved(pNode->m_id, 0);
}
else
{
// XXXMEH - we need to know about animations that
// involve sources before we know about the sources.
// Therefore, we need to ensure that the animate
// elements are put before the source elements.
UINT32 ulTS = INITIAL_STREAM1_TIMESTAMP;
if (pNode->m_tag == SMILAnimate ||
pNode->m_tag == SMILSet ||
pNode->m_tag == SMILAnimateColor ||
pNode->m_tag == SMILAnimateMotion)
{
ulTS = INITIAL_STREAM0_TIMESTAMP;
}
pNode->m_pElement->m_ulDelay = ulDelay;
pNode->m_pElement->m_ulTimestamp = ulTS;
pNode->m_pElement->m_bInsertedIntoTimeline = TRUE;
pNode->m_pElement->m_bHasBeenScheduled = TRUE;
// /This helps fix problem where time container has multiple
// begin conditions and, when second begin was being
// processed, wasn't being seen as having started before so
// prepForRestart() wasn't being called when it should.
// Allow more than one level, i.e., recurse up the tree to
// set this for all ancestor time containers:
SMILNode* pNextHigherSyncAncestor = pSyncAncestor;
while (pNextHigherSyncAncestor &&
pNextHigherSyncAncestor->m_pElement)
{
pNextHigherSyncAncestor->m_pElement->m_bInsertedIntoTimeline = TRUE;
pNextHigherSyncAncestor->m_pElement->m_bHasBeenScheduled = TRUE;
pNextHigherSyncAncestor = getSyncAncestor(
pNextHigherSyncAncestor);
}
insertElementByTimestamp(pNode->m_pElement);
}
}
}
cleanup:
return;
}
HX_RESULT
CSmilParser::trackRemoved(const char* pID,
UINT32 ulDuration)
{
HX_RESULT hr = HXR_OK;
SMILNode* pNode = NULL;
IHXBuffer* pBuf = NULL;
if(m_pIDMap->Lookup(pID, (void*&)pNode))
{
// add duration to parent element
if(pNode &&
pNode->m_pElement &&
pNode->m_pElement->m_pTimelineElement)
{
pNode->m_pElement->m_pTimelineElement->resetDuration(ulDuration);
}
}
return hr;
}
void
CSmilParser::resetTimelineElementDuration(const char* pID,
// /These durations must NOT include delay (for PR 79699 et al):
UINT32 ulPureDuration,
UINT32 ulPriorPureDuration)
{
#if defined(_DEBUG) && defined(XXXEHODGE_DEBUG_RESETTIMELINEELEMENTDUR_AND_DELAY)
{
FILE* f1 = ::fopen("c:\\smil2ResetTimelineDurOrDelay.txt", bFirstResetTimelineElementDuration?"w":"a+");
bFirstResetTimelineElementDuration = FALSE;
::fprintf(f1, "Element id = %s;\t%sresetting (pure) duration to %lu from %lu\n",
pID, ulPureDuration==ulPriorPureDuration?
#if XXXEH_TEST_THIS_MORE
"Skipping ":"",
#else
"":"",
#endif
ulPureDuration, ulPriorPureDuration);
::fclose(f1);
f1 = ::fopen("c:\\smil2AddDuration.txt", "a+");
::fprintf(f1, "\nElement id = %s;\t%sresetting duration to %lu from %lu\n\n",
pID, ulPureDuration==ulPriorPureDuration?
#if XXXEH_TEST_THIS_MORE
"Skipping ":"",
#else
"":"",
#endif
ulPureDuration, ulPriorPureDuration);
::fclose(f1);
}
#endif
SMILNode* pNode = NULL;
// /Fixes bug exposed by fixes for PR 59584 and others (by undoing the
// original fix for PR 61174(version1) and par version of PR 56686).
// Don't reset duration if it's the same, otherwise SourceUpdate will be
// created possibly prior to TrackDurationSet() even being called, which
// would cause this delay event to be used to possibly mess things up in
// rendererInitialized():
#if defined(XXXEH_TEST_THIS_MORE)
// /TEST THIS! A test file fails due to this when both are same,
// "..relatedToPR59584andPR62688(endsync1stWithRestartVersion..smil"
if (ulPureDuration == ulPriorPureDuration)
{
goto cleanup;
}
#endif
if(m_pIDMap->Lookup(pID, (void*&)pNode))
{
CSmilSourceUpdate* pUpdate = new CSmilSourceUpdate;
pUpdate->m_ulTimestamp = INITIAL_STREAM1_TIMESTAMP;
pUpdate->m_srcID = pID;
pUpdate->m_updateTag = UpdateDuration;
pUpdate->m_ulUpdatedDuration = ulPureDuration;
pUpdate->m_bDurationIsPureOfDelay = TRUE;
if(!m_pSourceUpdateList)
{
m_pSourceUpdateList = new CHXSimpleList;
}
m_pSourceUpdateList->AddTail(pUpdate);
insertElementByTimestamp(pUpdate);
}
#if defined(XXXEH_TEST_THIS_MORE)
cleanup:
#endif
return;
}
void
CSmilParser::resetTimelineElementDelay(const char* pID,
UINT32 ulDelay,
UINT32 ulPriorDelay)
{
#if defined(_DEBUG) && defined(XXXEHODGE_DEBUG_RESETTIMELINEELEMENTDUR_AND_DELAY)
{
FILE* f1 = ::fopen("c:\\smil2ResetTimelineDurOrDelay.txt", bFirstResetTimelineElementDuration?"w":"a+");
bFirstResetTimelineElementDuration = FALSE;
::fprintf(f1, "Element id = %s;\t%sresetting delay to %lu from %lu\n",
pID, ulDelay==ulPriorDelay?"Skipping ":"", ulDelay, ulPriorDelay);
::fclose(f1);
f1 = ::fopen("c:\\smil2AddDuration.txt", "a+");
::fprintf(f1, "\nElement id = %s;\t%sresetting delay to %lu from %lu\n\n",
pID, ulDelay==ulPriorDelay?"Skipping ":"", ulDelay, ulPriorDelay);
::fclose(f1);
}
#endif
SMILNode* pNode = NULL;
// /Fixes bug exposed by fixes for PR 59584 and others (by undoing the
// original fix for PR 61174(version1) and par version of PR 56686).
// Don't reset delay if it's the same, otherwise SourceUpdate will be
// created possibly prior to TrackDurationSet() even being called, which
// would cause this delay event to be used to possibly mess things up in
// rendererInitialized():
if (ulDelay == ulPriorDelay)
{
goto cleanup;
}
if(m_pIDMap->Lookup(pID, (void*&)pNode))
{
CSmilSourceUpdate* pUpdate = new CSmilSourceUpdate;
pUpdate->m_ulTimestamp = INITIAL_STREAM1_TIMESTAMP;
pUpdate->m_srcID = pID;
pUpdate->m_updateTag = UpdateDelay;
pUpdate->m_ulUpdatedDelay = ulDelay;
if(!m_pSourceUpdateList)
{
m_pSourceUpdateList = new CHXSimpleList;
}
m_pSourceUpdateList->AddTail(pUpdate);
insertElementByTimestamp(pUpdate);
}
cleanup:
return;
}
CSmilElement*
CSmilParser::findElement(const char* pID)
{
SMILNode* pNode = NULL;
if(m_pIDMap->Lookup(pID, (void*&)pNode))
{
return pNode->m_pElement;
}
return NULL;
}
const char*
CSmilParser::assignID(const char* pPrefix)
{
SafeSprintf(m_pVarName, 256, "%s_%ld", pPrefix, GetUniqueNumber());
return m_pVarName;
}
UINT16
CSmilParser::getFragmentGroup(const char* pFragment)
{
if(pFragment)
{
SMILNode* pNode = 0;
if(m_pIDMap->Lookup(pFragment, (void*&)pNode))
{
if(!pNode->m_bDelete)
{
if(pNode->m_tag == SMILAAnchor ||
pNode->m_tag == SMILSwitch)
{
SMILNode* pChildNode = getTimelineDescendent(pNode, NULL);
while(pChildNode)
{
if(!pChildNode->m_bDelete)
{
return pChildNode->m_nGroup;
}
pChildNode = getTimelineDescendent(pNode, pChildNode);
}
}
else if(pNode->m_tag == SMILAnchor ||
pNode->m_tag == SMILArea)
{
SMILNode* pParentNode = pNode->m_pParent;
if(pParentNode &&
!pParentNode->m_bDelete)
{
return pParentNode->m_nGroup;
}
}
else
{
return pNode->m_nGroup;
}
}
}
}
return 0;
}
UINT32
CSmilParser::getFragmentOffset(const char* pFragment,
//This BOOL will be set to FALSE if the fragment
// does not exist; this was necessary to fix PR 22655.
BOOL& bFragFoundAndResolved,
BOOL bResolveBeginOfFragmentTarget,
ULONG32 ulCurTime)
{
bFragFoundAndResolved = FALSE;
if(pFragment)
{
INT32 lAnchorBegin = 0;
SMILNode* pNode = NULL;
CSmilElement* pElement = NULL;
CSmilElement* pFragmentElement = NULL;
if(m_pIDMap->Lookup(pFragment, (void*&)pNode) &&
pNode->m_pElement)
{
pElement = pNode->m_pElement;
if(pNode->m_tag == SMILSwitch ||
pNode->m_tag == SMILAAnchor)
{
SMILNode* pChildNode = getTimelineDescendent(
pNode, NULL);
while(pChildNode)
{
if(!pChildNode->m_bDelete)
{
pFragmentElement = pChildNode->m_pElement;
break;
}
pChildNode = getTimelineDescendent(
pNode, pChildNode);
}
}
else if(pNode->m_tag == SMILAnchor ||
pNode->m_tag == SMILArea)
{
if(pElement->m_bBeginOffsetSet)
{
lAnchorBegin = pElement->m_lBeginOffset;
}
SMILNode* pParent = pNode->m_pParent;
if(pParent)
{
pFragmentElement = pParent->m_pElement;
}
}
else
{
pFragmentElement = pElement;
}
if(pFragmentElement)
{
bFragFoundAndResolved = TRUE;
//[SMIL 1.0 Compliance] Fixes PR 26464:
// Use delay (which already includes begin offset)
// if it's a valid value, else use begin offset
// without delay added (see comment below):
if(pFragmentElement->m_ulDelay != (UINT32)-1)
{
INT32 offset = pFragmentElement->m_ulDelay +
lAnchorBegin;
return (offset >= 0 ? (UINT32)offset: 0);
}
else if(pFragmentElement->m_bBeginOffsetSet)
{
//Changed this while fixing PR 26464:
// This used to return pFragmentElement->m_ulDelay +
// pFragmentElement->m_lBeginOffset + lAnchorBegin but
// the delay can already account for the begin if both
// are set so we'd end up seeking past where we were
// supposed to go by the amount of the begin offset.
// Also, we weren't even checking to see
// if delay was valid before using it (and now we're
// sure it is invalid per check above):
INT32 offset = pFragmentElement->m_lBeginOffset +
lAnchorBegin;
return (offset >= 0 ? (UINT32)offset: 0);
}
// /Fixes SMIL 2.0 Interop Linking tests #1.4 & #1.5:
// if we've been instructed to resolve this #-ref'd
// internally-linked element's delay, then we need to
// do so to the current time:
else if (bResolveBeginOfFragmentTarget &&
pFragmentElement->m_pTimelineElement)
{
SMILNode* pSyncAncestor =
getSyncAncestor(pFragmentElement->m_pNode);
// /Fixes PR 50848:
// /The following is needed to completely fix SMIL 2.0
// Interop Linking #1.5 (to make the clicked-on child of
// a seq go away when the clicked-to one starts):
if (pSyncAncestor && SMILSeq == pSyncAncestor->m_tag)
{
SMILNode* pSibling = pSyncAncestor->getFirstChild();
SMILNode* pPrevSibling = NULL;
while (pSibling)
{
if (pSibling->m_id ==
pFragmentElement->m_pNode->m_id)
{
break;
}
// /Fixes case where pFragmentElement has non-
// timeline-element parent, e.g., <a> or <switch>
else if (pFragmentElement->m_pNode->m_pParent !=
pSyncAncestor)
{
SMILNode* pFirstSiblingChild =
pSibling->getFirstChild();
if (pFirstSiblingChild &&
pFirstSiblingChild->m_id ==
pFragmentElement->m_pNode->m_id)
{
break;
}
}
pPrevSibling = pSibling;
pSibling = pSyncAncestor->getNextChild();
}
if (pPrevSibling)
{
// /XXXEH- TODO: if prev sib is not a timeline
// element, use its first child as prev sibling.
if (pPrevSibling->m_pElement &&
pPrevSibling->m_pElement->m_pTimelineElement)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -