📄 smldoc.cpp
字号:
pValues->SetPropertyULONG32("duration", 1);
//Set the PersistentComponentID.
pValues->SetPropertyULONG32("PersistentComponentID", m_ulPersistentComponentID);
//Tell the core this we don't want any
//TrackAdded callbacks because we don't
//have any groups.
pValues->SetPropertyULONG32("NoGroupsPresent", 1);
// Add the "NullBrush" property to the request headers
setProperty(pReqHeaders, "NullBrush", "1");
// Get the current group
IHXGroup* pGroup = NULL;
pMgr->GetGroup(usGroup, pGroup);
if (pGroup)
{
// Get the IHXGroup2 interface
IHXGroup2* pGroup2 = NULL;
pGroup->QueryInterface(IID_IHXGroup2, (void**) &pGroup2);
if (pGroup2)
{
// Add the track
pGroup2->AddTrack2(pValues, pReqHeaders);
}
HX_RELEASE(pGroup2);
}
HX_RELEASE(pGroup);
}
HX_RELEASE(pReqHeaders);
}
HX_RELEASE(pValues);
}
}
HX_RELEASE(pMgr);
}
}
#endif /* #if defined(HELIX_FEATURE_SMIL2_BRUSH) */
return retVal;
}
HX_RESULT
CSmilDocumentRenderer::handleElements()
{
HX_RESULT rc = HXR_OK;
if(m_pSmilParser)
{
//if(m_ulParseResult != HXR_STREAM_DONE)
//{
while(HXR_OK == rc)
{
rc = m_pSmilParser->handleNextElement(this);
}
m_ulParseResult = rc;
//}
}
return HXR_OK;
}
HX_RESULT CSmilDocumentRenderer::postParseSetup()
{
HX_RESULT retVal = HXR_OK;
// There are several things we cannot setup until
// we have received all of the CSmilElement's handleElement()
// methods up front.
//
// The first is that we want to set the SiteNeverBlts property
// of the site, but in order to do that, we need to know all
// the sources and all the animate elements.
if (m_pRegionMap)
{
// Run through the map
POSITION pos = m_pRegionMap->GetStartPosition();
while (pos)
{
const char* pszKey = NULL;
void* pVal = NULL;
m_pRegionMap->GetNextAssoc(pos, pszKey, pVal);
if (pVal)
{
// Get the region pointer
CSmilBasicRegion* pRegion = (CSmilBasicRegion*) pVal;
// Check if this region's site should
// have its SiteNeverBlts property set to "1".
// It should if:
// a) the backgroundColor is transparent
// b) backgroundColor is never animated
// c) backgroundColor is never overridden in a source
if (isTransparent(pRegion->m_ulBackgroundColor) &&
!isAttributeAnimated((const char*) pRegion->m_region,
kAttrNameBackgroundColor) &&
!isRegionBackgroundColorOverridden(pRegion))
{
setSiteProperty(pRegion->m_pSite, "SiteNeverBlts", "1");
}
}
}
}
return retVal;
}
HX_RESULT
CSmilDocumentRenderer::parseDimension(const char* pDimensionString,
REF(UINT32) ulValue,
REF(BOOL) bIsPercent)
{
HX_RESULT rc = HXR_OK;
if(!pDimensionString || strlen(pDimensionString) == 0)
{
ulValue = 0L;
//[SMIL 1.0 compliance] Helps fix PR 16542. The caller of this
// function should look at this return value to determine whether
// or not the string was empty (and thus 0 is returned in ulValue) or
// whether "0" or "0%" IS the string (and thus 0 is returned in
// ulValue along with HXR_OK):
rc = HXR_FAIL;
}
else
{
char* pEndPtr = 0;
ulValue = (UINT32)strtod(pDimensionString, &pEndPtr);
if(pEndPtr && strcmp(pEndPtr, "%") == 0)
{
bIsPercent = TRUE;
}
else
{
bIsPercent = FALSE;
}
}
return rc;
}
HX_RESULT CSmilDocumentRenderer::computeBoxDimension(CSmilBasicBox* pBox,
BoxDimension eDim)
{
HX_RESULT retVal = HXR_OK;
if (pBox)
{
// Clear the flag that says whether or
// not to compute our dimension based on
// our children
BOOL bPostResolve = FALSE;
// Have we already resolved our dimension?
if (!pBox->isResolved(eDim))
{
// We have NOT resolved our dimension yet,
// so we need to attempt to resolve it
HX_RESULT rv = pBox->computeDimension(eDim);
if (FAILED(rv))
{
// We could not resolve our dimension
// so we will have to try and resolve it
// from our children.
bPostResolve = TRUE;
}
}
if (pBox->m_pChildList)
{
// Now we run through our children, computing
// their dimensions
LISTPOSITION pos = pBox->m_pChildList->GetHeadPosition();
while (pos && SUCCEEDED(retVal))
{
CSmilBasicBox* pListBox = (CSmilBasicBox*) pBox->m_pChildList->GetNext(pos);
if (pListBox)
{
retVal = computeBoxDimension(pListBox, eDim);
}
}
if (SUCCEEDED(retVal) && bPostResolve)
{
retVal = pBox->resolveFromChildren(eDim);
}
}
}
return retVal;
}
void CSmilDocumentRenderer::clearResolvedFlags(CSmilBasicBox* pBox)
{
if (pBox)
{
// Clear the flags for this box
pBox->m_bWidthResolved = FALSE;
pBox->m_bHeightResolved = FALSE;
// Recurse through the children
if (pBox->m_pChildList)
{
LISTPOSITION pos = pBox->m_pChildList->GetHeadPosition();
while (pos)
{
CSmilBasicBox* pListBox =
(CSmilBasicBox*) pBox->m_pChildList->GetNext(pos);
clearResolvedFlags(pListBox);
}
}
}
}
void CSmilDocumentRenderer::resetSites(CSmilBasicBox* pBox, BOOL bOptimizeRedraws)
{
if (pBox)
{
IHXSite* pSite = pBox->m_pSite;
BOOL bIsRegion = FALSE;
if (pBox->m_pParent)
{
// This box has a parent, so it has to be a region
bIsRegion = TRUE;
}
if (pSite)
{
// Get the current position of the site
HXxPoint cPos = {0, 0};
pSite->GetPosition(cPos);
// Set the new position of the site
HXxPoint cNewPos = {pBox->m_Rect.left, pBox->m_Rect.top};
#if defined(HELIX_FEATURE_SMIL2_MULTIWINDOWLAYOUT)
#if defined(XXXMEH_DO_VIEWPORT_TLC) && defined(_WINDOWS)
if (pBox->m_pParent && !pBox->m_pParent->m_pParent)
{
// This has to be a region, so cast
CSmilBasicRegion* pReg = (CSmilBasicRegion*) pBox;
if (!pReg->m_bUnderRootLayout)
{
cNewPos.x += GetSystemMetrics(SM_CXFIXEDFRAME);
cNewPos.y += GetSystemMetrics(SM_CYFIXEDFRAME) + GetSystemMetrics(SM_CYCAPTION);
}
}
#endif
#endif /* #if defined(HELIX_FEATURE_SMIL2_MULTIWINDOWLAYOUT) */
// If the new position is different from
// the old position, then reset the position
if (cPos.x != cNewPos.x ||
cPos.y != cNewPos.y)
{
if (bIsRegion)
{
CSmilBasicRegion* pReg = (CSmilBasicRegion*) pBox;
MLOG_LAYOUT(m_pErrorMessages,
"CSmilDocumentRenderer::resetSites() region=%s site->SetPosition(%ld,%ld)\n",
(const char*) pReg->m_region, cNewPos.x, cNewPos.y);
}
pSite->SetPosition(cNewPos);
// Optimize out any site redraws if necessary
if (bOptimizeRedraws)
{
// If we are calling SetPosition() on this
// site, then the site code will automatically
// force a redraw on this site. Therefore, if
// we were planning on doing a ForceRedraw() on
// this site as a result of some animation, then
// it's no longer necessary
removePendingAnimationRedraw(pSite);
}
}
// Get the current size of the site
HXxSize cSize = {0, 0};
pSite->GetSize(cSize);
// Set the new size of the site
HXxSize cNewSize = {HXxRECT_WIDTH(pBox->m_Rect),
HXxRECT_HEIGHT(pBox->m_Rect)};
// If this is different from the size
// of the rect, then resize
if (cSize.cx != cNewSize.cx ||
cSize.cy != cNewSize.cy)
{
if (bIsRegion)
{
CSmilBasicRegion* pReg = (CSmilBasicRegion*) pBox;
MLOG_LAYOUT(m_pErrorMessages,
"CSmilDocumentRenderer::resetSites() region=%s site->SetSize(%ld,%ld)\n",
(const char*) pReg->m_region, cNewSize.cx, cNewSize.cy);
}
pSite->SetSize(cNewSize);
// Optimize out any site redraws if necessary
if (bOptimizeRedraws)
{
// If we are calling SetSize() on this
// site, then the site code will automatically
// force a redraw on this site. Therefore, if
// we were planning on doing a ForceRedraw() on
// this site as a result of some animation, then
// it's no longer necessary
removePendingAnimationRedraw(pSite);
}
// If this is a region, then we need to
// resize any renderers which are currently
// playing as well.
if (bIsRegion)
{
CSmilBasicRegion* pRegion = (CSmilBasicRegion*) pBox;
resetRendererSites(pRegion);
}
}
}
// Recurse through the children
if (pBox->m_pChildList)
{
LISTPOSITION pos = pBox->m_pChildList->GetHeadPosition();
while (pos)
{
CSmilBasicBox* pListBox =
(CSmilBasicBox*) pBox->m_pChildList->GetNext(pos);
resetSites(pListBox, bOptimizeRedraws);
}
}
}
}
void CSmilDocumentRenderer::resizeTopLevelBox(CSmilBasicBox* pBox,
HXxSize cOrigSize,
HXxSize cSize)
{
// A box is only top-level if it has no parent box
if (pBox && !pBox->m_pParent)
{
// Only resize if the current size is different
if (cSize.cx != HXxRECT_WIDTH(pBox->m_Rect) ||
cSize.cy != HXxRECT_HEIGHT(pBox->m_Rect))
{
MLOG_LAYOUT(m_pErrorMessages,
"CSmilDocumentRenderer::resizeTopLevelBox(0x%08x,(%ld,%ld),(%ld,%ld))\n",
pBox, cOrigSize.cx, cOrigSize.cy, cSize.cx, cSize.cy);
// Clear the resolved flags
clearResolvedFlags(pBox);
// Normally, we have to resolve a top-level box's
// dimensions just like anything else, but top-level
// boxes can be explicitly resized by the user by
// resizing the window. Therefore, we explicitly
// set the rectangle for this top-level box
pBox->m_Rect.left = 0;
pBox->m_Rect.top = 0;
if (pBox->m_eResizeBehavior == ResizePercentOnly ||
(pBox->m_eResizeBehavior == ResizeZoom && m_bDoNotZoom))
{
// If we are NOT zooming, then we simply use
// the new size. Also, this could be called in
// the case where we are using the media size
// to figure out the root-layout size. In that
// case, we don't zoom either.
pBox->m_Rect.right = cSize.cx;
pBox->m_Rect.bottom = cSize.cy;
}
else
{
// If we are zooming, then we re-calculate
// using the original top-level size and then
// scale the whole thing.
pBox->m_Rect.right = cOrigSize.cx;
pBox->m_Rect.bottom = cOrigSize.cy;
}
// We force resolution of the top-level site
pBox->m_bWidthResolved = TRUE;
pBox->m_bHeightResolved = TRUE;
// Compute left and right of the region rects
computeBoxDimension(pBox, BoxDimensionWidth);
// Compute top and bottom of the region rects
computeBoxDimension(pBox, BoxDimensionHeight);
// If we have zoom resize behavior, then we need to
// compute and set the zoom scale factors and then
// scale the rects
if (pBox->m_eResizeBehavior == ResizeZoom && !m_bDoNotZoom)
{
// Compute the x scale factor
double dScaleX = 1.0;
if (cOrigSize.cx > 0)
{
dScaleX = ((double) cSize.cx) / ((double) cOrigSize.cx);
}
// Compute the y scale factor
double dScaleY = 1.0;
if (cOrigSize.cy > 0)
{
dScaleY = ((double) cSize.cy) / ((double) cOrigSize.cy);
}
// Set all the scale factors
zoomRect(pBox, dScaleX, dScaleY);
}
// Turn on site composition if it's not already on
// We don't want to turn it off if it's already on
BOOL bInCompositionMode = isSiteCompositionModeON();
if (!bInCompositionMode)
{
turnSiteCompositionModeON();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -