sitewatc.cpp
上传用户:zhongxx05
上传日期:2007-06-06
资源大小:33641k
文件大小:26k
源码类别:

Symbian

开发平台:

C/C++

  1. /* ***** BEGIN LICENSE BLOCK ***** 
  2.  * Version: RCSL 1.0/RPSL 1.0 
  3.  *  
  4.  * Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved. 
  5.  *      
  6.  * The contents of this file, and the files included with this file, are 
  7.  * subject to the current version of the RealNetworks Public Source License 
  8.  * Version 1.0 (the "RPSL") available at 
  9.  * http://www.helixcommunity.org/content/rpsl unless you have licensed 
  10.  * the file under the RealNetworks Community Source License Version 1.0 
  11.  * (the "RCSL") available at http://www.helixcommunity.org/content/rcsl, 
  12.  * in which case the RCSL will apply. You may also obtain the license terms 
  13.  * directly from RealNetworks.  You may not use this file except in 
  14.  * compliance with the RPSL or, if you have a valid RCSL with RealNetworks 
  15.  * applicable to this file, the RCSL.  Please see the applicable RPSL or 
  16.  * RCSL for the rights, obligations and limitations governing use of the 
  17.  * contents of the file.  
  18.  *  
  19.  * This file is part of the Helix DNA Technology. RealNetworks is the 
  20.  * developer of the Original Code and owns the copyrights in the portions 
  21.  * it created. 
  22.  *  
  23.  * This file, and the files included with this file, is distributed and made 
  24.  * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
  25.  * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
  26.  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS 
  27.  * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 
  28.  * 
  29.  * Technology Compatibility Kit Test Suite(s) Location: 
  30.  *    http://www.helixcommunity.org/content/tck 
  31.  * 
  32.  * Contributor(s): 
  33.  *  
  34.  * ***** END LICENSE BLOCK ***** */ 
  35. // system
  36. #include <math.h>
  37. #include <time.h>     // smlparse.h dependency
  38. // include
  39. #include "hxtypes.h"
  40. #include "hxwintyp.h"
  41. #include "hxcom.h"
  42. #include "hxwin.h"
  43. #include "smiltype.h"
  44. #include "hxengin.h"
  45. #include "hxcore.h"  // smldoc.h   dependency
  46. #include "hxgroup.h" // smldoc.h   dependency
  47. #include "hxsite2.h" // smldoc.h   dependency
  48. #include "ihxpckts.h" // smldoc.h   dependency
  49. #include "hxvport.h" // smldoc.h   dependency
  50. #include "hxclsnk.h" // smldoc.h   dependency
  51. #include "hxmmrkr.h" // smldoc.h   dependency
  52. #include "hxinter.h" // smldoc.h   dependency
  53. #include "hxxml.h"   // smlparse.h dependency
  54. #include "hxerror.h"
  55. // pnmisc
  56. #include "hxwinver.h" // smlparse.h dependency
  57. #include "hxtick.h"
  58. // pncont
  59. #include "hxstring.h"
  60. #include "hxmap.h"
  61. #include "hxslist.h"
  62. // rnxmllib
  63. #include "hxxmlprs.h" // smlparse.h dependency
  64. // rmasmil
  65. #include "smlelem.h"
  66. #include "smlparse.h"
  67. // smlrendr
  68. #include "evnthook.h" // smldoc.h   dependency
  69. #include "siteuser.h" // smldoc.h   dependency
  70. #include "passivsw.h" // smldoc.h   dependency
  71. #include "layout.h"
  72. #include "smldoc.h"
  73. #include "sitewatc.h"
  74. // pndebug
  75. #include "smlrmlog.h"
  76. #include "hxheap.h"
  77. #ifdef _DEBUG
  78. #undef HX_THIS_FILE
  79. static const char HX_THIS_FILE[] = __FILE__;
  80. #endif
  81. CSmilSiteWatcher::CSmilSiteWatcher(CSmilDocumentRenderer* pDoc,
  82.                                    const char*            pID,
  83.                                    BOOL                   bIsChildSite,
  84.                                    const char*            pSourceID) :
  85.     m_id(pID),
  86.     m_SourceID(pSourceID)
  87. {
  88.     // Initialize the members
  89.     m_lRefCount              = 0;
  90.     m_pDoc                   = pDoc;
  91.     m_pSite                  = NULL;
  92.     m_Rect.m_dLeft           = 0.0;
  93.     m_Rect.m_eLeftType       = CSS2TypeAuto;
  94.     m_Rect.m_dTop            = 0.0;
  95.     m_Rect.m_eTopType        = CSS2TypeAuto;
  96.     m_Rect.m_dRight          = 0.0;
  97.     m_Rect.m_eRightType      = CSS2TypeAuto;
  98.     m_Rect.m_dBottom         = 0.0;
  99.     m_Rect.m_eBottomType     = CSS2TypeAuto;
  100.     m_Rect.m_dWidth          = 0.0;
  101.     m_Rect.m_eWidthType      = CSS2TypeAuto;
  102.     m_Rect.m_dHeight         = 0.0;
  103.     m_Rect.m_eHeightType     = CSS2TypeAuto;
  104.     m_RegPoint.m_dLeft       = 0.0;
  105.     m_RegPoint.m_eLeftType   = CSS2TypeAuto;
  106.     m_RegPoint.m_dTop        = 0.0;
  107.     m_RegPoint.m_eTopType    = CSS2TypeAuto;
  108.     m_RegPoint.m_dRight      = 0.0;
  109.     m_RegPoint.m_eRightType  = CSS2TypeAuto;
  110.     m_RegPoint.m_dBottom     = 0.0;
  111.     m_RegPoint.m_eBottomType = CSS2TypeAuto;
  112.     m_RegPoint.m_eRegAlign   = RegAlignTopLeft;
  113.     m_MediaSize.cx           = 0;
  114.     m_MediaSize.cy           = 0;
  115.     m_eResizeBehavior        = ResizeZoom;
  116.     m_dZoomScaleFactorX      = 1.0;
  117.     m_dZoomScaleFactorY      = 1.0;
  118.     m_bIsChildSite           = bIsChildSite;
  119.     m_bChangingSize          = FALSE;
  120.     m_bFirstSizeChange       = TRUE;
  121.     m_bMediaSizeSet          = FALSE;
  122.     m_bMediaIsBrush          = FALSE;
  123.     // Initialize the RegPoint
  124.     if(m_pDoc)
  125.     {
  126.         m_pDoc->AddRef();
  127.         // RegPoints can come from two places - they can
  128.         // either be idrefs or they can be predefined
  129.         CSmilSource* pSource = m_pDoc->getSource(pSourceID);
  130.         if (pSource)
  131.         {
  132.             // Check if this is a <brush>
  133.             if (pSource->m_pNode &&
  134.                 pSource->m_pNode->m_tag == SMILBrush)
  135.             {
  136.                 m_bMediaIsBrush = TRUE;
  137.             }
  138.             // Copy the Layout rect. This is the subregion
  139.             // positioning rect which was specified on the
  140.             // media element (i.e. - <img ... left="20" .../>)
  141.             m_Rect = pSource->m_Rect;
  142.             // Get the regPoint
  143.             if (pSource->m_bRegPointIsPredef)
  144.             {
  145.                 // Since the regPoint is predefined, then
  146.                 // there is no regAlign from the <regPoint>.
  147.                 // Therefore, we need to use the regAlign
  148.                 // that was specified with the source
  149.                 m_RegPoint.m_eRegAlign = pSource->m_eRegAlign;
  150.                 // For predefined regPoints, they are always
  151.                 // expressed in percentages, not in absolute lengths
  152.                 m_RegPoint.m_eLeftType = CSS2TypePercentage;
  153.                 m_RegPoint.m_eTopType  = CSS2TypePercentage;
  154.                 // Compute the regPoint
  155.                 switch (pSource->m_ePredefRegPoint)
  156.                 {
  157.                     case RegAlignTopLeft:
  158.                         {
  159.                             m_RegPoint.m_dLeft = 0.0;
  160.                             m_RegPoint.m_dTop  = 0.0;
  161.                         }
  162.                         break;
  163.                     case RegAlignTopMid:
  164.                         {
  165.                             m_RegPoint.m_dLeft = 50.0;
  166.                             m_RegPoint.m_dTop  =  0.0;
  167.                         }
  168.                         break;
  169.                     case RegAlignTopRight:
  170.                         {
  171.                             m_RegPoint.m_dLeft = 100.0;
  172.                             m_RegPoint.m_dTop  =   0.0;
  173.                         }
  174.                         break;
  175.                     case RegAlignMidLeft:
  176.                         {
  177.                             m_RegPoint.m_dLeft =  0.0;
  178.                             m_RegPoint.m_dTop  = 50.0;
  179.                         }
  180.                         break;
  181.                     case RegAlignCenter:
  182.                         {
  183.                             m_RegPoint.m_dLeft = 50.0;
  184.                             m_RegPoint.m_dTop  = 50.0;
  185.                         }
  186.                         break;
  187.                     case RegAlignMidRight:
  188.                         {
  189.                             m_RegPoint.m_dLeft = 100.0;
  190.                             m_RegPoint.m_dTop  =  50.0;
  191.                         }
  192.                         break;
  193.                     case RegAlignBottomLeft:
  194.                         {
  195.                             m_RegPoint.m_dLeft =   0.0;
  196.                             m_RegPoint.m_dTop  = 100.0;
  197.                         }
  198.                         break;
  199.                     case RegAlignBottomMid:
  200.                         {
  201.                             m_RegPoint.m_dLeft =  50.0;
  202.                             m_RegPoint.m_dTop  = 100.0;
  203.                         }
  204.                         break;
  205.                     case RegAlignBottomRight:
  206.                         {
  207.                             m_RegPoint.m_dLeft = 100.0;
  208.                             m_RegPoint.m_dTop  = 100.0;
  209.                         }
  210.                         break;
  211.                 }
  212.             }
  213.             else
  214.             {
  215.                 // The regPoint is not predefined, but rather
  216.                 // is an idref to a <regPoint> element. So look
  217.                 // up that element
  218.                 CSmilRegPoint* pRegPt = m_pDoc->getRegPoint(pSource->m_RegPoint);
  219.                 if (pRegPt)
  220.                 {
  221.                     // We simply need to copy the RegPoint struct
  222.                     // from the CSmilRegPoint element
  223.                     m_RegPoint = pRegPt->m_RegPoint;
  224.                     // <regPoint> elements have a default "regAlign"
  225.                     // attribute. However, the media object element
  226.                     // can override this regAlign value.
  227.                     if (pSource->m_bRegAlignSpecified)
  228.                     {
  229.                         // The media object element DID specify
  230.                         // a regAlign attribute, so this attribute
  231.                         // overrides the regAlign attribute in the
  232.                         // <regPoint> element.
  233.                         m_RegPoint.m_eRegAlign = pSource->m_eRegAlign;
  234.                     }
  235.                 }
  236.             }
  237.             // Now we can compute the fit attribute. The default
  238.             // fit attribute is specified with the <region>. However,
  239.             // the media object element can override this attribute.
  240.             // So first we need to get the region.
  241.             CSmilBasicRegion* pRegion = m_pDoc->getRegionByID(m_id);
  242.             if (pRegion)
  243.             {
  244.                 // Initially assign the region's fit value
  245.                 m_eFit = pRegion->m_eFit;
  246.             }
  247.             // Now if the source has specified a fit
  248.             // value, then override the region's fit value
  249.             if (pSource->m_bFitSpecified)
  250.             {
  251.                 m_eFit = pSource->m_eFit;
  252.             }
  253.         }
  254.     }
  255. }
  256. CSmilSiteWatcher::~CSmilSiteWatcher()
  257. {
  258.     close();
  259. }
  260. HX_RESULT CSmilSiteWatcher::close()
  261. {
  262.     HX_RELEASE(m_pDoc);
  263.     HX_RELEASE(m_pSite);
  264.     return HXR_OK;
  265. }
  266. void CSmilSiteWatcher::SetZoomScaleFactors(double dX, double dY)
  267. {
  268.     if (dX > 0.0)
  269.     {
  270.         m_dZoomScaleFactorX = dX;
  271.     }
  272.     if (dY > 0.0)
  273.     {
  274.         m_dZoomScaleFactorY = dY;
  275.     }
  276. }
  277. void CSmilSiteWatcher::SetResizeBehavior(ResizeBehavior eBehavior)
  278. {
  279.     m_eResizeBehavior = eBehavior;
  280. }
  281. STDMETHODIMP CSmilSiteWatcher::QueryInterface(REFIID riid, void** ppvObj)
  282. {
  283.     HX_RESULT retVal = HXR_OK;
  284.     if(IsEqualIID(riid, IID_IUnknown))
  285.     {
  286.         AddRef();
  287.         *ppvObj = this;
  288.     }
  289.     else if(IsEqualIID(riid, IID_IHXSiteWatcher))
  290.     {
  291.         AddRef();
  292.         *ppvObj = (IHXSiteWatcher*) this;
  293.     }
  294.     else
  295.     {
  296.         *ppvObj = NULL;
  297.         retVal  = HXR_NOINTERFACE;
  298.     }
  299.     return retVal;
  300. }
  301. STDMETHODIMP_(ULONG32) CSmilSiteWatcher::AddRef()
  302. {
  303.     return InterlockedIncrement(&m_lRefCount);
  304. }
  305. STDMETHODIMP_(ULONG32) CSmilSiteWatcher::Release()
  306. {
  307.     if(InterlockedDecrement(&m_lRefCount) > 0)
  308.     {
  309.         return m_lRefCount;
  310.     }
  311.     delete this;
  312.     return 0;
  313. }
  314. STDMETHODIMP CSmilSiteWatcher::AttachSite(IHXSite* pSite)
  315. {
  316.     HX_RESULT retVal = HXR_OK;
  317.     HX_RELEASE(m_pSite);
  318.     m_pSite = pSite;
  319.     if(m_pSite)
  320.     {
  321.         m_pSite->AddRef();
  322.     }
  323.     return retVal;
  324. }
  325. STDMETHODIMP CSmilSiteWatcher::DetachSite()
  326. {
  327.     HX_RESULT retVal = HXR_OK;
  328.     HX_RELEASE(m_pSite);
  329.     return HXR_OK;
  330. }
  331. STDMETHODIMP CSmilSiteWatcher::ChangingPosition(HXxPoint      oldPos,
  332.                                                 REF(HXxPoint) newPos)
  333. {
  334.     HX_RESULT retVal = HXR_OK;
  335.     if(!m_bChangingSize)
  336.     {
  337.         CSmilBasicRegion* pRegion = m_pDoc->getRegionByID(m_id);
  338.         if(pRegion && m_bMediaSizeSet)
  339.         {
  340.             // Pick the rect to use as the parent. If we 
  341.             // have a ResizeBehavior of Zoom and are indeed
  342.             // zooming, then use the unzoomed parent width.
  343.             // Otherwise, use the regular zoomed parent width.
  344.             HXxRect cRect = pRegion->m_rect;
  345.             if ((m_dZoomScaleFactorX != 1.0 ||
  346.                  m_dZoomScaleFactorY != 1.0) &&
  347.                 m_eResizeBehavior == ResizeZoom)
  348.             {
  349.                 cRect = pRegion->m_RectNoZoom;
  350.             }
  351.             // First we need to compute the subregion rect. We can't
  352.             // do this just once, since the subregion rect parameters
  353.             // may be getting animated.
  354.             HXxRect cSubRegionRect = {0, 0, 0, 0};
  355.             CSmilBasicRegion::resolveDimension(m_Rect.m_dLeft,  m_Rect.m_eLeftType,
  356.                                                m_Rect.m_dRight, m_Rect.m_eRightType,
  357.                                                m_Rect.m_dWidth, m_Rect.m_eWidthType,
  358.                                                TRUE, HXxRECT_WIDTH(cRect),
  359.                                                cSubRegionRect.left,
  360.                                                cSubRegionRect.right);
  361.             CSmilBasicRegion::resolveDimension(m_Rect.m_dTop,    m_Rect.m_eTopType,
  362.                                                m_Rect.m_dBottom, m_Rect.m_eBottomType,
  363.                                                m_Rect.m_dHeight, m_Rect.m_eHeightType,
  364.                                                TRUE, HXxRECT_HEIGHT(cRect),
  365.                                                cSubRegionRect.top,
  366.                                                cSubRegionRect.bottom);
  367.             // The calculation above was done in the space of the
  368.             // region. The calculations below are done in the space
  369.             // of the region's parent, so we need to offset the subregion
  370.             // rect by the region's upper left corner.
  371.             cSubRegionRect.left   += cRect.left;
  372.             cSubRegionRect.top    += cRect.top;
  373.             cSubRegionRect.right  += cRect.left;
  374.             cSubRegionRect.bottom += cRect.top;
  375.             // Now we need to compute the absolute coordinates
  376.             // of the regPoint. Since the regPoint could be in
  377.             // percentage values, and the size of the region
  378.             // could be changing under animation, then we 
  379.             // must recompute the absolute coordinates of the
  380.             // regPoint every time. This regPoint is in the
  381.             // space of the region's PARENT and not in the space
  382.             // of the region's rect itself.
  383.             HXxPoint cRegPoint = {0, 0};
  384.             m_pDoc->computeRegPoint(cSubRegionRect,
  385.                                     m_RegPoint,
  386.                                     cRegPoint);
  387.             // Now that we know the absolute coordinates
  388.             // of the regPoint, then we can compute the 
  389.             // media layout within the region rect. Note
  390.             // that the following calculation takes place
  391.             // in the coordinate space of the region's PARENT,
  392.             // and not the region's rect itself.
  393.             HXxRect  cMediaRect = {0, 0, 0, 0};
  394.             retVal = m_pDoc->computeMediaLayout(cSubRegionRect,
  395.                                                 m_eFit,
  396.                                                 cRegPoint,
  397.                                                 m_RegPoint.m_eRegAlign,
  398.                                                 m_MediaSize,
  399.                                                 cMediaRect,
  400.                                                 m_bMediaIsBrush);
  401.             if (SUCCEEDED(retVal))
  402.             {
  403.                 // Now since the calculation of the media size was
  404.                 // done in the space of the region's PARENT, then
  405.                 // and we need to set the size of the media in the
  406.                 // coordinate space of the REGION, then we need
  407.                 // to translate the media rect to the coordinate
  408.                 // space of the region.
  409.                 cMediaRect.left   -= cRect.left;
  410.                 cMediaRect.top    -= cRect.top;
  411.                 cMediaRect.right  -= cRect.left;
  412.                 cMediaRect.bottom -= cRect.top;
  413.                 // Now we can assign the new position
  414.                 newPos.x = cMediaRect.left;
  415.                 newPos.y = cMediaRect.top;
  416.                 // If we have a resize behavior of Zoom, then
  417.                 // we compute everything off of the original root-layout
  418.                 // size, and then simply scale by the zoom factors.
  419.                 if ((m_dZoomScaleFactorX != 1.0 ||
  420.                      m_dZoomScaleFactorY != 1.0) &&
  421.                     m_eResizeBehavior == ResizeZoom)
  422.                 {
  423.                     newPos.x = (INT32) floor(m_dZoomScaleFactorX * ((double) newPos.x) + 0.5);
  424.                     newPos.y = (INT32) floor(m_dZoomScaleFactorY * ((double) newPos.y) + 0.5);
  425.                 }
  426.             }
  427.         }
  428.     }
  429.     MLOG_LAYOUT(NULL,
  430.                 "%lutChangingPosition((%ld,%ld),(%ld,%ld)) m_id=%s m_SourceID=%sn",
  431.                 HX_GET_BETTERTICKCOUNT(),
  432.                 oldPos.x, oldPos.y, newPos.x, newPos.y,
  433.                 (const char*) m_id,
  434.                 (const char*) m_SourceID);
  435.     return retVal;
  436. }
  437. STDMETHODIMP CSmilSiteWatcher::ChangingSize(HXxSize      oldSize,
  438.                                             REF(HXxSize) newSize)
  439. {
  440.     HX_RESULT retVal = HXR_OK;
  441.     if(!m_bChangingSize &&
  442.        (newSize.cx != 0 || newSize.cy != 0))
  443.     {
  444.         CSmilBasicRegion* pRegion = m_pDoc->getRegionByID(m_id);
  445.         if(pRegion)
  446.         {
  447.             // For almost all renderers, here's the sequence of
  448.             // events: the core calls them with IHXSite::AttachSite()
  449.             // and in that call, they call IHXSite::SetSize() with
  450.             // the native size of their media. Therefore, we will assume
  451.             // that the first call we get will be the native size of
  452.             // the media.
  453.             BOOL bForceSetPosition = FALSE;
  454.             if (m_bFirstSizeChange)
  455.             {
  456.                 MLOG_LAYOUT(NULL,
  457.                             "Media size for %s is (%ld,%ld)n",
  458.                             (const char*) m_SourceID,
  459.                             newSize.cx, newSize.cy);
  460.                 // Save off the native media size
  461.                 m_MediaSize        = newSize;
  462.                 m_bMediaSizeSet    = TRUE;
  463.                 m_bFirstSizeChange = FALSE;
  464.                 bForceSetPosition  = TRUE;
  465.                 if (m_pDoc)
  466.                 {
  467.                     m_pDoc->setMediaNativeSize(m_SourceID, newSize);
  468.                 }
  469.                 // XXXMEH - this is legacy, which saves
  470.                 // the media size into the region. However,
  471.                 // this SHOULD NOT be used, since multiple media
  472.                 // can play to the same region. TODO - if we 
  473.                 // can, make sure this is not used and then
  474.                 // delete it from the region object.
  475.                 pRegion->m_originalMediaSize = newSize;
  476.                 pRegion->m_bMediaSizeSet     = TRUE;
  477.             }
  478.             // Pick the rect to use as the parent. If we 
  479.             // have a ResizeBehavior of Zoom and are indeed
  480.             // zooming, then use the unzoomed parent width.
  481.             // Otherwise, use the regular zoomed parent width.
  482.             HXxRect cRect = pRegion->m_rect;
  483.             if ((m_dZoomScaleFactorX != 1.0 ||
  484.                  m_dZoomScaleFactorY != 1.0) &&
  485.                 m_eResizeBehavior == ResizeZoom)
  486.             {
  487.                 cRect = pRegion->m_RectNoZoom;
  488.             }
  489.             // First we need to compute the subregion rect. We can't
  490.             // do this just once, since the subregion rect parameters
  491.             // may be getting animated.
  492.             HXxRect cSubRegionRect = {0, 0, 0, 0};
  493.             CSmilBasicRegion::resolveDimension(m_Rect.m_dLeft,  m_Rect.m_eLeftType,
  494.                                                m_Rect.m_dRight, m_Rect.m_eRightType,
  495.                                                m_Rect.m_dWidth, m_Rect.m_eWidthType,
  496.                                                TRUE, HXxRECT_WIDTH(cRect),
  497.                                                cSubRegionRect.left,
  498.                                                cSubRegionRect.right);
  499.             CSmilBasicRegion::resolveDimension(m_Rect.m_dTop,    m_Rect.m_eTopType,
  500.                                                m_Rect.m_dBottom, m_Rect.m_eBottomType,
  501.                                                m_Rect.m_dHeight, m_Rect.m_eHeightType,
  502.                                                TRUE, HXxRECT_HEIGHT(cRect),
  503.                                                cSubRegionRect.top,
  504.                                                cSubRegionRect.bottom);
  505.             // The calculation above was done in the space of the
  506.             // region. The calculations below are done in the space
  507.             // of the region's parent, so we need to offset the subregion
  508.             // rect by the region's upper left corner.
  509.             cSubRegionRect.left   += cRect.left;
  510.             cSubRegionRect.top    += cRect.top;
  511.             cSubRegionRect.right  += cRect.left;
  512.             cSubRegionRect.bottom += cRect.top;
  513.             // Now we need to compute the absolute coordinates
  514.             // of the regPoint. Since the regPoint could be in
  515.             // percentage values, and the size of the region
  516.             // could be changing under animation, then we 
  517.             // must recompute the absolute coordinates of the
  518.             // regPoint every time. This regPoint is in the
  519.             // space of the region's PARENT and not in the space
  520.             // of the region's rect itself.
  521.             HXxPoint cRegPoint = {0, 0};
  522.             m_pDoc->computeRegPoint(cSubRegionRect,
  523.                                     m_RegPoint,
  524.                                     cRegPoint);
  525.             // Now that we know the absolute coordinates
  526.             // of the regPoint, then we can compute the 
  527.             // media layout within the region rect. Note
  528.             // that the following calculation takes place
  529.             // in the coordinate space of the region's PARENT,
  530.             // and not the region's rect itself.
  531.             HXxRect  cMediaRect = {0, 0, 0, 0};
  532.             retVal = m_pDoc->computeMediaLayout(cSubRegionRect,
  533.                                                 m_eFit,
  534.                                                 cRegPoint,
  535.                                                 m_RegPoint.m_eRegAlign,
  536.                                                 m_MediaSize,
  537.                                                 cMediaRect,
  538.                                                 m_bMediaIsBrush);
  539.             if (SUCCEEDED(retVal))
  540.             {
  541.                 // Now since the calculation of the media size was
  542.                 // done in the space of the region's PARENT, then
  543.                 // and we need to set the size of the media in the
  544.                 // coordinate space of the REGION, then we need
  545.                 // to translate the media rect to the coordinate
  546.                 // space of the region.
  547.                 cMediaRect.left   -= cRect.left;
  548.                 cMediaRect.top    -= cRect.top;
  549.                 cMediaRect.right  -= cRect.left;
  550.                 cMediaRect.bottom -= cRect.top;
  551.                 // So now the new width and height
  552.                 // can be calculated.
  553.                 newSize.cx = HXxRECT_WIDTH(cMediaRect);
  554.                 newSize.cy = HXxRECT_HEIGHT(cMediaRect);
  555.                 // If we have a resize behavior of Zoom, then
  556.                 // we compute everything off of the original root-layout
  557.                 // size, and then simply scale by the zoom factors.
  558.                 if ((m_dZoomScaleFactorX != 1.0 ||
  559.                      m_dZoomScaleFactorY != 1.0) &&
  560.                     m_eResizeBehavior == ResizeZoom)
  561.                 {
  562.                     newSize.cx = (INT32) floor(m_dZoomScaleFactorX * ((double) newSize.cx) + 0.5);
  563.                     newSize.cy = (INT32) floor(m_dZoomScaleFactorY * ((double) newSize.cy) + 0.5);
  564.                 }
  565.                 // Set the current media size to this value
  566.                 // XXXMEH - TODO is this actually used anywhere? We
  567.                 // should not really have a media size set into
  568.                 // the region object anywhere, since multiple
  569.                 // media can play to the same region
  570.                 pRegion->m_mediaSize = newSize;
  571.                 // As mentioned above, the renderers will usually 
  572.                 // call IHXSite::SetSize() when they are FIRST called
  573.                 // with IHXSite::AttachSite(). However, since renderers
  574.                 // don't have an idea of relative position to other renderers,
  575.                 // then they rarely call IHXSite::SetPosition(). Therefore,
  576.                 // if this is the first time through, we will need to explicitly
  577.                 // call IHXSite::SetPosition().
  578.                 if (bForceSetPosition)
  579.                 {
  580.                     // Since we have a site watcher, then it
  581.                     // doesn't matter what we pass in, the site
  582.                     // watcher will change it to what it needs to
  583.                     // be. So pass in some arbitrary position.
  584.                     HXxPoint cPos = {1, 1};
  585.                     if (m_pSite)
  586.                     {
  587.                         m_pSite->SetPosition(cPos);
  588.                     }
  589.                 }
  590.                 // If this is a scrolling site, then set the flag
  591.                 if (m_eFit == FitScroll && m_pSite)
  592.                 {
  593.                     IHXValues* pValues = NULL;
  594.                     m_pSite->QueryInterface(IID_IHXValues, (void**) &pValues);
  595.                     if (pValues)
  596.                     {
  597.                         pValues->SetPropertyULONG32("ScrollingSite", 1);
  598.                     }
  599.                     HX_RELEASE(pValues);
  600.                 }
  601.             }
  602.         }
  603.     }
  604.     MLOG_LAYOUT(NULL,
  605.                 "%lutChangingSize((%ld,%ld),(%ld,%ld)) m_id=%s m_SourceID=%sn",
  606.                 HX_GET_BETTERTICKCOUNT(),
  607.                 oldSize.cx, oldSize.cy, newSize.cx, newSize.cy,
  608.                 (const char*) m_id,
  609.                 (const char*) m_SourceID);
  610.     return retVal;
  611. }