📄 sm1doc.cpp
字号:
/* check for valid region constraints */
BOOL bRegionError = FALSE;
char errorBuf[256]; /* Flawfinder: ignore */
//[SMIL 1.0 compliance] helps fix PR 24630; separate width & height logic
if((!m_bRootLayoutWidthSet &&
(bLeftIsPercent || bWidthIsPercent)) ||
(!m_bRootLayoutHeightSet &&
(bTopIsPercent || bHeightIsPercent)) )
{
//XXXE: needs err msg: "Region can't use % without root-layout"
rc = HXR_FAIL;
SafeSprintf(errorBuf, 256, "region %s",
(const char*)pElement->m_pNode->m_id);
CSmil1SMILSyntaxErrorHandler errHandler(m_pContext);
errHandler.ReportError(SMILErrorBadAttribute, errorBuf, 0);
return rc;
}
if(m_bRootLayoutWidthSet)
{
if(bLeftIsPercent)
{
ulLeft = (UINT32)(((float)ulLeft/100.0) * m_ulRootLayoutWidth);
}
if(bWidthIsPercent)
{
ulWidth = (UINT32)(((float)ulWidth/100.0) * m_ulRootLayoutWidth);
}
}
if(m_bRootLayoutHeightSet)
{
if(bTopIsPercent)
{
ulTop = (UINT32)(((float)ulTop/100.0) * m_ulRootLayoutHeight);
}
if(bHeightIsPercent)
{
ulHeight = (UINT32)(((float)ulHeight/100.0) * m_ulRootLayoutHeight);
}
}
if(m_ulNoRootLayoutHeight < (ulTop + ulHeight))
{
m_ulNoRootLayoutHeight = ulTop + ulHeight;
}
if(m_ulNoRootLayoutWidth < (ulLeft + ulWidth))
{
m_ulNoRootLayoutWidth = ulLeft + ulWidth;
}
//[SMIL 1.0 compliance] Helps fix PR 16542:
if(m_pSmilParser)
{
//If we're in full-compliance mode and someone enters a
// width="0" or width="0%", we should leave it as 0. We
// know that they omitted width or height (which is returned as 0
// from parseDimension), if the return value is HXR_FAIL:
if (!ulWidth && HXR_FAIL == rsltW)
{
bWidthUnspecified = TRUE;
}
if (!ulHeight && HXR_FAIL == rsltH)
{
bHeightUnspecified = TRUE;
}
}
pRect->left = ulLeft;
pRect->top = ulTop;
pRect->right = ulLeft + ulWidth;
pRect->bottom = ulTop + ulHeight;
return rc;
}
HX_RESULT
CSmil1DocumentRenderer::handleRegion(CSmil1Region* pElement)
{
HX_RESULT rc = HXR_OK;
HXxRect rect;
rect.left = 0;
rect.right = 0;
rect.top = 0;
rect.bottom = 0;
BOOL bWidthUnspecified, bHeightUnspecified;
if(HXR_OK != regionToRect(pElement, &rect,
//[SMIL 1.0 compliance] Helps fix PR 16542; these are passed
// by reference and set to TRUE if width or height (respectively)
// is not explicitly set:
bWidthUnspecified, bHeightUnspecified))
{
rc = HXR_FAIL;
}
else
{
CSmil1BasicRegion* pRegion = new CSmil1BasicRegion(pElement->m_pNode->m_id, rect,
pElement->m_zIndex, pElement->m_fit, pElement->m_ulBgColor,
pElement->m_bBgColorSet, FALSE,
bWidthUnspecified, bHeightUnspecified);
(*m_pRegionMap)[(const char*)pElement->m_pNode->m_id] = pRegion;
}
return rc;
}
HX_RESULT
CSmil1DocumentRenderer::handleRootLayout(CSmil1RootLayout* pElement)
{
HX_RESULT rc = HXR_OK;
m_bRootLayoutWidthSet = !pElement->m_bWidthUnspecified;
m_bRootLayoutHeightSet = !pElement->m_bHeightUnspecified;
m_ulRootLayoutHeight = pElement->m_ulHeight;
m_ulRootLayoutWidth = pElement->m_ulWidth;
m_ulRootLayoutBGColor = pElement->m_ulBgColor;
return rc;
}
HX_RESULT
CSmil1DocumentRenderer::handleAddGroup(CSmil1AddGroup* pElement)
{
HX_RESULT rc = HXR_OK;
if (m_bInRAM20 && !m_bLastGroupInRAM20 && m_ulGroupIndex)
{
return rc;
}
if(!m_pGroupMap)
{
m_pGroupMap = new CHXMapLongToObj;
}
IHXPlayer* pPlayer = m_pParent->getPlayer();
IHXGroupManager* pMgr = 0;
if(HXR_OK == pPlayer->QueryInterface(IID_IHXGroupManager, (void**)&pMgr))
{
IHXGroup* pGroup = NULL;
IHXGroup2* pGroup2 = NULL;
if (m_pParent->m_bUseNestedMeta && 0 == m_ulGroupIndex)
{
if (m_bLastGroupInRAM20)
{
rc = pMgr->CreateGroup(pGroup);
}
else
{
HX_ASSERT(pMgr->GetGroupCount());
rc = pMgr->GetCurrentGroup(m_uGroupIndexWithin);
rc = pMgr->GetGroup(m_uGroupIndexWithin, pGroup);
}
}
else
{
rc = pMgr->CreateGroup(pGroup);
}
if(HXR_OK == rc)
// release pGroup when m_pGroupMap is destructed
{
CHXHeader* pGroupValues = new CHXHeader;
pGroupValues->AddRef();
if(pElement->m_ulDuration != (UINT32)-1)
{
pGroupValues->SetPropertyULONG32("duration", pElement->m_ulDuration);
}
pGroupValues->SetPropertyULONG32("total_tracks", pElement->m_nTotalTracks);
pGroupValues->SetPropertyULONG32("initial_tracks", pElement->m_nInitTracks);
pGroupValues->SetPropertyULONG32("PersistentComponentID", m_ulPersistentComponentID);
if (m_bLastGroupInRAM20)
{
pGroupValues->SetPropertyULONG32("LastGroupInRAM20", 1);
}
// copy all the node values to group values
IHXValues* pValues = pElement->m_pValues;
if(pValues)
{
IHXBuffer* pBuf = NULL;
const char* pName = NULL;
HX_RESULT res =
pValues->GetFirstPropertyCString(pName, pBuf);
while(HXR_OK == res)
{
pGroupValues->SetPropertyCString(pName, pBuf);
HX_RELEASE(pBuf);
res = pValues->GetNextPropertyCString(pName, pBuf);
}
}
pGroup->SetGroupProperties(pGroupValues);
if (HXR_OK == pGroup->QueryInterface(IID_IHXGroup2, (void**)&pGroup2))
{
pGroup2->SetPersistentComponentProperties(m_ulPersistentComponentID,
pGroupValues);
}
HX_RELEASE(pGroup2);
HX_RELEASE(pGroupValues);
if (m_pParent->m_bUseNestedMeta && 0 == m_ulGroupIndex)
{
if (m_bLastGroupInRAM20)
{
pMgr->AddGroup(pGroup);
}
else
{
GroupAdded(m_uGroupIndexWithin, pGroup);
}
}
else
{
pMgr->AddGroup(pGroup);
}
m_ulTrackIndex = 0;
m_ulGroupIndex++;
(*m_pGroupMap)[pElement->m_nGroup] = pGroup;
}
}
HX_RELEASE(pMgr);
return rc;
}
void
CSmil1DocumentRenderer::setProperty(IHXValues* pValues,
const char* pName, const char* pValue)
{
IHXBuffer* pBuf = 0;
IHXCommonClassFactory* pFactory = m_pParent->getFactory();
if(HXR_OK == pFactory->CreateInstance(CLSID_IHXBuffer,
(void**)&pBuf))
{
pBuf->Set((BYTE*)pValue, strlen(pValue)+1);
pValues->SetPropertyCString(pName, pBuf);
pBuf->Release();
}
}
HX_RESULT
CSmil1DocumentRenderer::convertURL(const char* pURL, CHXString& newURL)
{
CHXURL urlObj(pURL);
IHXValues* pHeader = urlObj.GetProperties();
IHXBuffer* pBuffer = NULL;
if(!pHeader)
{
return HXR_FAIL;
}
if(HXR_OK == pHeader->GetPropertyBuffer(PROPERTY_SCHEME, pBuffer))
{
// fully qualified URL
newURL = pURL;
HX_RELEASE(pBuffer);
}
else
{
// relative URL
// if it starts with '/', make it relative to the root of
// the URL prefix
if(*pURL == '/')
{
newURL = m_pParent->getURLRoot() + pURL;
}
else if (strnicmp(pURL, URL_COMMAND, sizeof(URL_COMMAND) - 1) == 0)
{
newURL = pURL;
}
else
{
newURL = m_pParent->getURLPrefix() + pURL;
}
}
HX_RELEASE(pHeader);
return HXR_OK;
}
HX_RESULT
CSmil1DocumentRenderer::handleSource(CSmil1Source* pElement)
{
HX_RESULT rc = HXR_OK;
CHXString urlString;
convertURL(pElement->m_src, urlString);
if (!m_pRepeatIDMap)
{
m_pRepeatIDMap = new CHXMapStringToOb;
}
IHXGroup* pGroup = 0;
if(m_pGroupMap &&
m_pGroupMap->Lookup(pElement->m_pNode->m_nGroup, (void*&)pGroup))
{
IHXCommonClassFactory* pFactory = m_pParent->getFactory();
IHXValues* pValues = 0;
if(HXR_OK == pFactory->CreateInstance(CLSID_IHXValues,
(void**)&pValues))
{
pValues->SetPropertyULONG32("PersistentComponentID", m_ulPersistentComponentID);
setProperty(pValues, "url", urlString);
setProperty(pValues, "id", pElement->m_pNode->m_id);
setProperty(pValues, "repeatid", pElement->m_pNode->m_repeatid);
setProperty(pValues, "playto", pElement->m_region);
if(pElement->m_region.GetLength() > 0)
{
// save original region name in track values
setProperty(pValues, "region", pElement->m_region);
}
setProperty(pValues, "fill", pElement->m_fill);
setProperty(pValues, "track-hint", pElement->m_pNode->m_trackHint);
UINT32 ulDelay = 0;
if(pElement->m_ulDelay != (UINT32)-1)
{
//if(pElement->m_ulBeginOffset != (UINT32)-1)
//{
// pValues->SetPropertyULONG32("delay", pElement->m_ulDelay +
// pElement->m_ulBeginOffset);
//}
//else
//{
ulDelay = pElement->m_ulDelay + m_ulPersistentComponentDelay;
//}
}
else
{
ulDelay = m_ulPersistentComponentDelay;
}
if (ulDelay)
{
pValues->SetPropertyULONG32("delay", ulDelay);
}
if(pElement->m_ulDuration != (UINT32)-1)
{
pValues->SetPropertyULONG32("duration", pElement->m_ulDuration);
}
if(pElement->m_ulMaxDuration != (UINT32)-1)
{
pValues->SetPropertyULONG32("maxduration", pElement->m_ulMaxDuration);
}
if(pElement->m_ulClipBegin != (UINT32)-1)
{
pValues->SetPropertyULONG32("start", pElement->m_ulClipBegin);
}
if(pElement->m_ulClipEnd != (UINT32)-1)
{
pValues->SetPropertyULONG32("end", pElement->m_ulClipEnd);
}
if (pElement->m_pNode->m_repeatTag !=
RepeatUnknown)
{
pValues->SetPropertyULONG32("repeatTag", pElement->m_pNode->m_repeatTag);
}
if (pElement->m_bIndefiniteDuration)
{
pValues->SetPropertyULONG32("indefiniteduration", TRUE);
}
// add arbitrary name-value pairs to track
if(pElement->m_pNode->m_pValues)
{
IHXValues* pSrcValues = pElement->m_pNode->m_pValues;
const char* pName = 0;
IHXBuffer* pValue = 0;
HX_RESULT rCode = pSrcValues->GetFirstPropertyCString(
pName, pValue);
while(HXR_OK == rCode)
{
// skip the values we already have or have overridden...
if((strcasecmp(pName, "url") != 0) &&
(strcasecmp(pName, "id") != 0) &&
(strcasecmp(pName, "playto") != 0) &&
(strcasecmp(pName, "fill") != 0))
{
setProperty(pValues, pName,
(const char*)pValue->GetBuffer());
}
HX_RELEASE(pValue);
rCode = pSrcValues->GetNextPropertyCString(
pName, pValue);
}
HX_RELEASE(pValue);
}
#ifdef _DEBUG
// just resolve this puppy at the outset and send
// to an output file
if(m_bShowDependencies)
{
FILE* fp = fopen(SMILDEPFILE, "a");
if(fp)
{
fprintf(fp, "src %s url %s group %d delay %ld\n",
(const char*)pElement->m_pNode->m_id,
(const char*)urlString,
pElement->m_pNode->m_nGroup,
(pElement->m_ulBeginOffset != (UINT32)-1) ?
pElement->m_ulDelay + pElement->m_ulBeginOffset :
pElement->m_ulDelay);
fclose(fp);
}
// determine duration resolution
// NOTE - this will give lame results
// for values that exceed ulNominalDuration
const UINT32 ulNominalDuration = 60000; // 1 min nominal
UINT32 ulDuration = ulNominalDuration;
if(pElement->m_ulClipEnd != (UINT32)-1)
{
ulDuration = pElement->m_ulClipEnd;
}
if(pElement->m_ulDuration != (UINT32)-1)
{
ulDuration = pElement->m_ulDuration;
}
if(pElement->m_ulBeginOffset != (UINT32)-1)
{
ulDuration += pElement->m_ulBeginOffset;
}
if(pElement->m_ulEndOffset != (UINT32)-1)
{
ulDuration -= pElement->m_ulEndOffset;
}
if(pElement->m_ulClipBegin != (UINT32)-1)
{
ulDuration -= pElement->m_ulClipBegin;
}
m_pSmilParser->durationResolved(pElement->m_pNode->m_id, ulDuration);
}
else
{
#if defined(PRE_SHAZAM_SMIL_1_0_CODE)
IHXGroup* pTempGroup = NULL;
if (m_pRepeatIDMap->Lookup(pElement->m_pNode->m_repeatid, (void*&)pTempGroup))
{
IHXGroup2* pTempGroup2 = NULL;
if (HXR_OK == pTempGroup->QueryInterface(IID_IHXGroup2, (void**)&pTempGroup2))
{
pTempGroup2->AddRepeatTrack(pValues);
}
HX_RELEASE(pTempGroup2);
}
else
#else
// /The following was added for SHAZAM since
// IHXGroup2's AddRepeatTrack() has been deprecated
// in favor of calling IHXTrack's AddTrack():
BOOL bRepeatTrackHandled = FALSE;
SMIL1PlayToAssoc* pPlayToAssoc = NULL;
if(m_pPlayToAssocList)
{
CHXSimpleList::Iterator i = m_pPlayToAssocList->Begin();
for ( ;i!=m_pPlayToAssocList->End() && !bRepeatTrackHandled; ++i)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -