sitewatc.cpp
上传用户:dangjiwu
上传日期:2013-07-19
资源大小:42019k
文件大小:27k
源码类别:

Symbian

开发平台:

Visual C++

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