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

Symbian

开发平台:

Visual C++

  1. /* ***** BEGIN LICENSE BLOCK *****
  2.  * Source last modified: $Id: animattr.cpp,v 1.1.22.1 2004/07/09 01:58:01 hubbe 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>
  52. // include
  53. #include "hxtypes.h"
  54. #include "hxwintyp.h"
  55. #include "hxcom.h"
  56. #include "hxxml.h"
  57. #include "smiltype.h"
  58. // pnmisc
  59. #include "hxwinver.h"
  60. #include "hxparse.h"
  61. // pncont
  62. #include "hxslist.h"
  63. // rnxmllib
  64. #include "hxxmlprs.h"
  65. // rmasmil
  66. #include "smlparse.h"
  67. #include "animattr.h"
  68. CAttr::CAttr(UINT32 ulAttrName, const char* pszStr)
  69. {
  70.     m_lLastError = HXR_OK;
  71.     m_ulAttrName = ulAttrName;
  72.     m_ulAttrType = kAttrTypeString;
  73.     m_dValue[0]  = 0.0;
  74.     m_dValue[1]  = 0.0;
  75.     m_dValue[2]  = 0.0;
  76.     m_dValue[3]  = 0.0;
  77.     m_eType[0]   = CSS2TypeAuto;
  78.     m_eType[1]   = CSS2TypeAuto;
  79.     m_eType[2]   = CSS2TypeAuto;
  80.     m_eType[3]   = CSS2TypeAuto;
  81.     m_pszValue   = NULL;
  82.     if (m_ulAttrName == kAttrNameLeft   ||
  83.         m_ulAttrName == kAttrNameTop    ||
  84.         m_ulAttrName == kAttrNameRight  ||
  85.         m_ulAttrName == kAttrNameBottom ||
  86.         m_ulAttrName == kAttrNameWidth  ||
  87.         m_ulAttrName == kAttrNameHeight)
  88.     {
  89.         m_ulAttrType = kAttrTypeRealScalar;
  90.         if (pszStr)
  91.         {
  92.             UINT32 ulIndex = (m_ulAttrName == kAttrNameTop ? 1 : 0);
  93.             BOOL   bRel    = FALSE;
  94.             m_lLastError   = ParsePosLenValue(pszStr, m_dValue[ulIndex], bRel);
  95.             if (SUCCEEDED(m_lLastError))
  96.             {
  97.                 m_eType[ulIndex] = (bRel ? CSS2TypePercentage : CSS2TypeLength);
  98.             }
  99.         }
  100.     }
  101.     else if (m_ulAttrName == kAttrNameBackgroundColor ||
  102.              m_ulAttrName == kAttrNameColor)
  103.     {
  104.         m_ulAttrType = kAttrTypeRealVector;
  105.         if (pszStr)
  106.         {
  107.             UINT32   ulColor = 0;
  108.             CSS2Type eType   = CSS2TypeTransparent;
  109.             m_lLastError     = CSmilParser::parseColor(pszStr, ulColor, eType);
  110.             if (SUCCEEDED(m_lLastError))
  111.             {
  112.                 m_dValue[0] = (double) ((ulColor & 0x00FF0000) >> 16);
  113.                 m_dValue[1] = (double) ((ulColor & 0x0000FF00) >>  8);
  114.                 m_dValue[2] = (double)  (ulColor & 0x000000FF);
  115.                 m_dValue[3] = (double) ((ulColor & 0xFF000000) >> 24);
  116.             }
  117.         }
  118.     }
  119.     else if (m_ulAttrName == kAttrNameZIndex)
  120.     {
  121.         m_ulAttrType = kAttrTypeRealScalar;
  122.         if (pszStr)
  123.         {
  124.             m_dValue[0]  = atof(pszStr);
  125.         }
  126.     }
  127.     else if (m_ulAttrName == kAttrNameSoundLevel)
  128.     {
  129.         m_ulAttrType = kAttrTypeRealScalar;
  130.         if (pszStr)
  131.         {
  132.             char* pEndPtr = NULL;
  133.             m_dValue[0]   = strtod(pszStr, &pEndPtr);
  134.             if (!pEndPtr || (pEndPtr && *pEndPtr != '%'))
  135.             {
  136.                 m_lLastError = HXR_FAIL;
  137.             }
  138.         }
  139.     }
  140.     else if (m_ulAttrName == kAttrNameMediaOpacity ||
  141.              m_ulAttrName == kAttrNameBackgroundOpacity)
  142.     {
  143.         m_ulAttrType = kAttrTypeRealScalar;
  144.         if (pszStr)
  145.         {
  146.             UINT32 ulOpacity = 0;
  147.             m_lLastError     = HXParseOpacity(pszStr, ulOpacity);
  148.             if (SUCCEEDED(m_lLastError))
  149.             {
  150.                 m_dValue[0] = (double) ulOpacity;
  151.             }
  152.         }
  153.     }
  154.     else if (m_ulAttrName == kAttrNameCoords ||
  155.              m_ulAttrName == kAttrNameValue)
  156.     {
  157.         m_ulAttrType = kAttrTypeString;
  158.         if (pszStr)
  159.         {
  160.             m_pszValue = new char [strlen(pszStr) + 1];
  161.             if (m_pszValue)
  162.             {
  163.                 strcpy(m_pszValue, pszStr); /* Flawfinder: ignore */
  164.             }
  165.             else
  166.             {
  167.                 m_lLastError = HXR_OUTOFMEMORY;
  168.             }
  169.         }
  170.     }
  171.     else if (m_ulAttrName == kAttrNameLeftTop)
  172.     {
  173.         m_ulAttrType = kAttrTypeRealVector;
  174.         if (pszStr)
  175.         {
  176.             // SPEC: coordinate-pair ::= ( coordinate comma-wsp coordinate )
  177.             //       coordinate      ::= num
  178.             //       num             ::= Number
  179.             //       comma-wsp       ::= S (spacechar|",") S
  180.             //       S               ::= spacechar*
  181.             //       spacechar       ::= (#x20 | #x9 | #xD | #xA)
  182.             //
  183.             // Here we parse coordinate-pair's
  184.             //
  185.             // Allocate a buffer to hold a copy
  186.             char* pszTmp = new char [strlen(pszStr) + 1];
  187.             if (pszTmp)
  188.             {
  189.                 // Copy the string
  190.                 strcpy(pszTmp, pszStr); /* Flawfinder: ignore */
  191.                 // Parse the string
  192.                 UINT32 ulNumFound = 0;
  193.                 char*  pszToken   = strtok(pszTmp, " trn,");
  194.                 while (pszToken && SUCCEEDED(m_lLastError) && ulNumFound < 2)
  195.                 {
  196.                     // Parse the value
  197.                     BOOL bRel    = FALSE;
  198.                     m_lLastError = ParsePosLenValue(pszToken, m_dValue[ulNumFound], bRel);
  199.                     if (SUCCEEDED(m_lLastError))
  200.                     {
  201.                         // Set the type
  202.                         m_eType[ulNumFound] = (bRel ? CSS2TypePercentage : CSS2TypeLength);
  203.                         // Increment the number parsed
  204.                         ulNumFound++;
  205.                         // Get the next token
  206.                         pszToken = strtok(NULL, " trn,");
  207.                     }
  208.                 }
  209.                 if (SUCCEEDED(m_lLastError))
  210.                 {
  211.                     // Make sure we parsed exactly two
  212.                     if (ulNumFound != 2)
  213.                     {
  214.                         // We found less than 2
  215.                         m_lLastError = HXR_FAIL;
  216.                     }
  217.                 }
  218.             }
  219.             else
  220.             {
  221.                 m_lLastError = HXR_OUTOFMEMORY;
  222.             }
  223.         }
  224.     }
  225. }
  226. CAttr::CAttr(UINT32 ulAttrName,
  227.              double dVal0, CSS2Type eType0,
  228.              double dVal1, CSS2Type eType1,
  229.              double dVal2, CSS2Type eType2,
  230.              double dVal3, CSS2Type eType3)
  231. {
  232.     m_lLastError = HXR_OK;
  233.     m_ulAttrName = ulAttrName;
  234.     m_ulAttrType = kAttrTypeString;
  235.     m_dValue[0]  = dVal0;
  236.     m_dValue[1]  = dVal1;
  237.     m_dValue[2]  = dVal2;
  238.     m_dValue[3]  = dVal3;
  239.     m_eType[0]   = eType0;
  240.     m_eType[1]   = eType1;
  241.     m_eType[2]   = eType2;
  242.     m_eType[3]   = eType3;
  243.     m_pszValue   = NULL;
  244.     if (m_ulAttrName == kAttrNameLeft         ||
  245.         m_ulAttrName == kAttrNameTop          ||
  246.         m_ulAttrName == kAttrNameRight        ||
  247.         m_ulAttrName == kAttrNameBottom       ||
  248.         m_ulAttrName == kAttrNameWidth        ||
  249.         m_ulAttrName == kAttrNameHeight       ||
  250.         m_ulAttrName == kAttrNameZIndex       ||
  251.         m_ulAttrName == kAttrNameSoundLevel   ||
  252.         m_ulAttrName == kAttrNameMediaOpacity ||
  253.         m_ulAttrName == kAttrNameBackgroundOpacity)
  254.     {
  255.         m_ulAttrType   = kAttrTypeRealScalar;
  256.     }
  257.     else if (m_ulAttrName == kAttrNameBackgroundColor ||
  258.              m_ulAttrName == kAttrNameColor           ||
  259.              m_ulAttrName == kAttrNameLeftTop)
  260.     {
  261.         m_ulAttrType   = kAttrTypeRealVector;
  262.     }
  263. }
  264. CAttr::CAttr(const CAttr& rAttr)
  265. {
  266.     m_lLastError = rAttr.m_lLastError;
  267.     m_ulAttrName = rAttr.m_ulAttrName;
  268.     m_ulAttrType = rAttr.m_ulAttrType;
  269.     m_dValue[0]  = rAttr.m_dValue[0];
  270.     m_dValue[1]  = rAttr.m_dValue[1];
  271.     m_dValue[2]  = rAttr.m_dValue[2];
  272.     m_dValue[3]  = rAttr.m_dValue[3];
  273.     m_eType[0]   = rAttr.m_eType[0];
  274.     m_eType[1]   = rAttr.m_eType[1];
  275.     m_eType[2]   = rAttr.m_eType[2];
  276.     m_eType[3]   = rAttr.m_eType[3];
  277.     m_pszValue   = NULL;
  278.     if (rAttr.m_pszValue)
  279.     {
  280.         m_pszValue = new char [strlen(rAttr.m_pszValue) + 1];
  281.         if (m_pszValue)
  282.         {
  283.             strcpy(m_pszValue, rAttr.m_pszValue); /* Flawfinder: ignore */
  284.         }
  285.         else
  286.         {
  287.             m_lLastError = HXR_OUTOFMEMORY;
  288.         }
  289.     }
  290. }
  291. CAttr::~CAttr()
  292. {
  293.     HX_VECTOR_DELETE(m_pszValue);
  294. }
  295. double CAttr::Dist(CAttr* pAttr1, CAttr* pAttr2, CAttr* pDepend)
  296. {
  297.     double dRet = 0.0;
  298.     if (Compatible(pAttr1, pAttr2))
  299.     {
  300.         if (pAttr1->m_ulAttrType == kAttrTypeRealScalar ||
  301.             pAttr1->m_ulAttrType == kAttrTypeRealVector)
  302.         {
  303.             double dSum = 0.0;
  304.             for (UINT32 i = 0; i < kVectorSize; i++)
  305.             {
  306.                 double dDiff = GetAbsolute(pAttr2, i, pDepend) -
  307.                                GetAbsolute(pAttr1, i, pDepend);
  308.                 dSum += dDiff * dDiff;
  309.             }
  310.             dRet = sqrt(dSum);
  311.         }
  312.     }
  313.     return dRet;
  314. }
  315. double CAttr::GetAbsolute(CAttr* pAttr, UINT32 i, CAttr* pDepend)
  316. {
  317.     double dRet = 0.0;
  318.     if (i < kVectorSize)
  319.     {
  320.         dRet = pAttr->m_dValue[i];
  321.         if (pAttr->IsRelative(i) && pDepend && !pDepend->IsRelative(i))
  322.         {
  323.             dRet = pAttr->m_dValue[i] * pDepend->m_dValue[i] / 100.0;
  324.         }
  325.     }
  326.     return dRet;
  327. }
  328. void CAttr::Interp(CAttr* pAttr1, double t1,
  329.                    CAttr* pAttr2, double t2,
  330.                    double t, CAttr* pDepend)
  331. {
  332.     if (Compatible(pAttr1, pAttr2) &&
  333.         t1 < t2 && t1 <= t && t <= t2)
  334.     {
  335.         // Copy the first attribute
  336.         *this = *pAttr1;
  337.         // Perform the interpolation
  338.         if (pAttr1->m_ulAttrType == kAttrTypeRealScalar ||
  339.             pAttr1->m_ulAttrType == kAttrTypeRealVector)
  340.         {
  341.             double dFract = (t - t1) / (t2 - t1);
  342.             for (UINT32 i = 0; i < kVectorSize; i++)
  343.             {
  344.                 double d1 = pAttr1->m_dValue[i];
  345.                 double d2 = pAttr2->m_dValue[i];
  346.                 if (pAttr1->IsRelative(i) != pAttr2->IsRelative(i) &&
  347.                     pDepend && !pDepend->IsRelative(i))
  348.                 {
  349.                     // If we are trying to interpolate between
  350.                     // an absolute and relative value, we will first
  351.                     // convert the relative value to absolute
  352.                     if (pAttr1->IsRelative(i) && !pAttr2->IsRelative(i))
  353.                     {
  354.                         // Convert attribute 1 to absolute
  355.                         d1 = GetAbsolute(pAttr1, i, pDepend);
  356.                     }
  357.                     else
  358.                     {
  359.                         // Convert attribute 2 to absolute
  360.                         d2 = GetAbsolute(pAttr2, i, pDepend);
  361.                     }
  362.                     // Since we made sure that both attributes were
  363.                     // absolute, then the result must be absolute as well.
  364.                     m_eType[i] = CSS2TypeLength;
  365.                 }
  366.                 m_dValue[i] = d1 + (d2 - d1) * dFract;
  367.             }
  368.         }
  369.     }
  370. }
  371. void CAttr::Add(CAttr* pAttr, CAttr* pDepend)
  372. {
  373.     if (Compatible(this, pAttr))
  374.     {
  375.         if (m_ulAttrType == kAttrTypeRealScalar ||
  376.             m_ulAttrType == kAttrTypeRealVector)
  377.         {
  378.             for (UINT32 i = 0; i < kVectorSize; i++)
  379.             {
  380.                 double d1 = m_dValue[i];
  381.                 double d2 = pAttr->m_dValue[i];
  382.                 if (IsRelative(i) != pAttr->IsRelative(i) &&
  383.                     pDepend && !pDepend->IsRelative(i))
  384.                 {
  385.                     // If we are trying to add an absolute value
  386.                     // to a relative value, we will first
  387.                     // convert the relative value to absolute
  388.                     if (IsRelative(i) && !pAttr->IsRelative(i))
  389.                     {
  390.                         // Convert attribute 1 to absolute
  391.                         d1 = GetAbsolute(this, i, pDepend);
  392.                     }
  393.                     else
  394.                     {
  395.                         // Convert attribute 2 to absolute
  396.                         d2 = GetAbsolute(pAttr, i, pDepend);
  397.                     }
  398.                     // Since we made sure that both attributes were
  399.                     // absolute, then the result must be absolute as well.
  400.                     m_eType[i] = CSS2TypeLength;
  401.                 }
  402.                 // Add the values
  403.                 m_dValue[i] = d1 + d2;
  404.             }
  405.         }
  406.     }
  407. }
  408. void CAttr::Mult(double dMult)
  409. {
  410.     if (m_ulAttrType == kAttrTypeRealScalar ||
  411.         m_ulAttrType == kAttrTypeRealVector)
  412.     {
  413.         for (UINT32 i = 0; i < kVectorSize; i++)
  414.         {
  415.             m_dValue[i] *= dMult;
  416.         }
  417.     }
  418. }
  419. void CAttr::Clamp()
  420. {
  421.     if (m_ulAttrName == kAttrNameBackgroundColor ||
  422.         m_ulAttrName == kAttrNameColor)
  423.     {
  424.         for (UINT32 i = 0; i < kVectorSize; i++)
  425.         {
  426.             // Round to nearest integer
  427.             m_dValue[i] = floor(m_dValue[i] + 0.5);
  428.             // Clip bottom
  429.             if (m_dValue[i] < 0.0)
  430.             {
  431.                 m_dValue[i] = 0.0;
  432.             }
  433.             // Clip top
  434.             if (m_dValue[i] > 255.0)
  435.             {
  436.                 m_dValue[i] = 255.0;
  437.             }
  438.         }
  439.     }
  440.     else if (m_ulAttrName == kAttrNameZIndex)
  441.     {
  442.         // Round to nearest integer
  443.         m_dValue[0] = floor(m_dValue[0] + 0.5);
  444.         // Clip bottom
  445.         if (m_dValue[0] < 0.0)
  446.         {
  447.             m_dValue[0] = 0.0;
  448.         }
  449.     }
  450.     else if (m_ulAttrName == kAttrNameSoundLevel)
  451.     {
  452.         // Clip bottom
  453.         if (m_dValue[0] < 0.0)
  454.         {
  455.             m_dValue[0] = 0.0;
  456.         }
  457.     }
  458.     else if (m_ulAttrName == kAttrNameMediaOpacity ||
  459.              m_ulAttrName == kAttrNameBackgroundOpacity)
  460.     {
  461.         // Clip bottom
  462.         if (m_dValue[0] < 0.0)
  463.         {
  464.             m_dValue[0] = 0.0;
  465.         }
  466.         // Clip top
  467.         if (m_dValue[0] > 255.0)
  468.         {
  469.             m_dValue[0] = 255.0;
  470.         }
  471.     }
  472. }
  473. double CAttr::GetValueDouble(UINT32 i) const
  474. {
  475.     double dRet = 0.0;
  476.     if (i < kVectorSize)
  477.     {
  478.         dRet = m_dValue[i];
  479.     }
  480.     return dRet;
  481. }
  482. CSS2Type CAttr::GetCSS2Type(UINT32 i) const
  483. {
  484.     CSS2Type eRet = CSS2TypeAuto;
  485.     if (i < kVectorSize)
  486.     {
  487.         eRet = m_eType[i]; 
  488.     }
  489.     return eRet;
  490. }
  491. BOOL CAttr::IsRelative(UINT32 i) const
  492. {
  493.     BOOL bRet = FALSE;
  494.     if (i < kVectorSize)
  495.     {
  496.         bRet = (m_eType[i] == CSS2TypePercentage ? TRUE : FALSE);
  497.     }
  498.     return bRet;
  499. }
  500. const char* CAttr::GetValueString(UINT32 i) const
  501. {
  502.     return m_pszValue;
  503. }
  504. CAttr& CAttr::operator  = (const CAttr& rAttr)
  505. {
  506.     m_lLastError = rAttr.m_lLastError;
  507.     m_ulAttrName = rAttr.m_ulAttrName;
  508.     m_ulAttrType = rAttr.m_ulAttrType;
  509.     m_dValue[0]  = rAttr.m_dValue[0];
  510.     m_dValue[1]  = rAttr.m_dValue[1];
  511.     m_dValue[2]  = rAttr.m_dValue[2];
  512.     m_dValue[3]  = rAttr.m_dValue[3];
  513.     m_eType[0]   = rAttr.m_eType[0];
  514.     m_eType[1]   = rAttr.m_eType[1];
  515.     m_eType[2]   = rAttr.m_eType[2];
  516.     m_eType[3]   = rAttr.m_eType[3];
  517.     HX_VECTOR_DELETE(m_pszValue);
  518.     if (rAttr.m_pszValue)
  519.     {
  520.         m_pszValue = new char [strlen(rAttr.m_pszValue) + 1];
  521.         if (m_pszValue)
  522.         {
  523.             strcpy(m_pszValue, rAttr.m_pszValue); /* Flawfinder: ignore */
  524.         }
  525.         else
  526.         {
  527.             m_lLastError = HXR_OUTOFMEMORY;
  528.         }
  529.     }
  530.     return *this;
  531. }
  532. BOOL CAttr::Compatible(CAttr* pAttr1, CAttr* pAttr2)
  533. {
  534.     BOOL bRet = FALSE;
  535.     if (pAttr1 && pAttr2)
  536.     {
  537.         if (pAttr1->m_ulAttrName == pAttr2->m_ulAttrName &&
  538.             pAttr1->m_ulAttrType == pAttr2->m_ulAttrType)
  539.         {
  540.             bRet = TRUE;
  541.         }
  542.         else if (pAttr1->m_ulAttrName == kAttrNameLeftTop)
  543.         {
  544.             if (pAttr2->m_ulAttrName == kAttrNameLeft ||
  545.                 pAttr2->m_ulAttrName == kAttrNameTop)
  546.             {
  547.                 bRet = TRUE;
  548.             }
  549.         }
  550.         else if (pAttr2->m_ulAttrName == kAttrNameLeftTop)
  551.         {
  552.             if (pAttr1->m_ulAttrName == kAttrNameLeft ||
  553.                 pAttr1->m_ulAttrName == kAttrNameTop)
  554.             {
  555.                 bRet = TRUE;
  556.             }
  557.         }
  558.     }
  559.     return bRet;
  560. }
  561. HX_RESULT CAttr::ParsePosLenValue(const char* pszStr,
  562.                                   double&     rdValue,
  563.                                   BOOL&       rbIsPercent)
  564. {
  565.     HX_RESULT retVal = HXR_OK;
  566.     if (pszStr)
  567.     {
  568.         // Parse the numeric value
  569.         char* pEndPtr = NULL;
  570.         rdValue       = strtod(pszStr, &pEndPtr);
  571.         // Now decide if it was a percent or not
  572.         if (pEndPtr && *pEndPtr == '%')
  573.         {
  574.             rbIsPercent = TRUE;
  575.         }
  576.         else
  577.         {
  578.             rbIsPercent = FALSE;
  579.         }
  580.     }
  581.     else
  582.     {
  583.         retVal = HXR_FAIL;
  584.     }
  585.     return retVal;
  586. }