void
nsMathMLmmultiscriptsFrame::ProcessAttributes()
{
  mSubScriptShift = 0;
  mSupScriptShift = 0;

  // check if the subscriptshift attribute is there
  nsAutoString value;
  GetAttribute(mContent, mPresentationData.mstyle,
               nsGkAtoms::subscriptshift_, value);
  if (!value.IsEmpty()) {
    nsCSSValue cssValue;
    if (ParseNumericValue(value, cssValue) && cssValue.IsLengthUnit()) {
      mSubScriptShift = CalcLength(PresContext(), mStyleContext, cssValue);
    }
  }
  // check if the superscriptshift attribute is there
  GetAttribute(mContent, mPresentationData.mstyle,
               nsGkAtoms::superscriptshift_, value);
  if (!value.IsEmpty()) {
    nsCSSValue cssValue;
    if (ParseNumericValue(value, cssValue) && cssValue.IsLengthUnit()) {
      mSupScriptShift = CalcLength(PresContext(), mStyleContext, cssValue);
    }
  }
}
static void
ProcessTranslatePart(float& aResult,
                     const nsCSSValue& aValue,
                     nsStyleContext* aContext,
                     nsPresContext* aPresContext,
                     PRBool& aCanStoreInRuleTree,
                     nscoord aSize, float aAppUnitsPerMatrixUnit)
{
  nscoord offset = 0;
  float percent = 0.0f;

  if (aValue.GetUnit() == eCSSUnit_Percent) {
    percent = aValue.GetPercentValue();
  } else if (aValue.IsCalcUnit()) {
    nsRuleNode::ComputedCalc result =
      nsRuleNode::SpecifiedCalcToComputedCalc(aValue, aContext, aPresContext,
                                              aCanStoreInRuleTree);
    percent = result.mPercent;
    offset = result.mLength;
  } else {
    offset = CalcLength(aValue, aContext, aPresContext,
                         aCanStoreInRuleTree);
  }

  aResult = (percent * NSAppUnitsToFloatPixels(aSize, aAppUnitsPerMatrixUnit)) + 
            NSAppUnitsToFloatPixels(offset, aAppUnitsPerMatrixUnit);
}
/* virtual */ nsresult
nsMathMLmsupFrame::Place(nsRenderingContext& aRenderingContext,
                         PRBool               aPlaceOrigin,
                         nsHTMLReflowMetrics& aDesiredSize)
{
  // extra spacing after sup/subscript
  nscoord scriptSpace = nsPresContext::CSSPointsToAppUnits(0.5f); // 0.5pt as in plain TeX

  // check if the superscriptshift attribute is there
  nsAutoString value;
  nscoord supScriptShift = 0;
  GetAttribute(mContent, mPresentationData.mstyle,
               nsGkAtoms::superscriptshift_, value);
  if (!value.IsEmpty()) {
    nsCSSValue cssValue;
    if (ParseNumericValue(value, cssValue) && cssValue.IsLengthUnit()) {
      supScriptShift = CalcLength(PresContext(), mStyleContext, cssValue);
    }
  }

  return nsMathMLmsupFrame::PlaceSuperScript(PresContext(), 
                                             aRenderingContext,
                                             aPlaceOrigin,
                                             aDesiredSize,
                                             this,
                                             supScriptShift,
                                             scriptSpace);
}
/* static */ void
nsMathMLFrame::ParseNumericValue(const nsString&   aString,
                                 nscoord*          aLengthValue,
                                 uint32_t          aFlags,
                                 nsPresContext*    aPresContext,
                                 nsStyleContext*   aStyleContext)
{
  nsCSSValue cssValue;

  if (!nsMathMLElement::ParseNumericValue(aString, cssValue, aFlags,
                                          aPresContext->Document())) {
    // Invalid attribute value. aLengthValue remains unchanged, so the default
    // length value is used.
    return;
  }

  nsCSSUnit unit = cssValue.GetUnit();

  if (unit == eCSSUnit_Percent || unit == eCSSUnit_Number) {
    // Relative units. A multiple of the default length value is used.
    *aLengthValue = NSToCoordRound(*aLengthValue * (unit == eCSSUnit_Percent ?
                                                    cssValue.GetPercentValue() :
                                                    cssValue.GetFloatValue()));
    return;
  }
  
  // Absolute units.
  *aLengthValue = CalcLength(aPresContext, aStyleContext, cssValue);
}
void
nsMathMLmspaceFrame::ProcessAttributes(nsPresContext* aPresContext)
{
  /*
  parse the attributes

  width  = number h-unit 
  height = number v-unit 
  depth  = number v-unit 
  */

  nsAutoString value;
  nsCSSValue cssValue;

  // width 
  mWidth = 0;
  if (NS_CONTENT_ATTR_HAS_VALUE == GetAttribute(mContent, mPresentationData.mstyle,
                   nsMathMLAtoms::width_, value)) {
    if ((ParseNumericValue(value, cssValue) ||
         ParseNamedSpaceValue(mPresentationData.mstyle, value, cssValue)) &&
         cssValue.IsLengthUnit()) {
      mWidth = CalcLength(aPresContext, mStyleContext, cssValue);
    }
  }

  // height
  mHeight = 0;
  if (NS_CONTENT_ATTR_HAS_VALUE == GetAttribute(mContent, mPresentationData.mstyle,
                   nsMathMLAtoms::height_, value)) {
    if ((ParseNumericValue(value, cssValue) ||
         ParseNamedSpaceValue(mPresentationData.mstyle, value, cssValue)) &&
         cssValue.IsLengthUnit()) {
      mHeight = CalcLength(aPresContext, mStyleContext, cssValue);
    }
  }

  // depth
  mDepth = 0;
  if (NS_CONTENT_ATTR_HAS_VALUE == GetAttribute(mContent, mPresentationData.mstyle,
                   nsMathMLAtoms::depth_, value)) {
    if ((ParseNumericValue(value, cssValue) ||
         ParseNamedSpaceValue(mPresentationData.mstyle, value, cssValue)) &&
         cssValue.IsLengthUnit()) {
      mDepth = CalcLength(aPresContext, mStyleContext, cssValue);
    }
  }
}
Beispiel #6
0
///---------------------------------------------------------------------------------
/// very slow
///---------------------------------------------------------------------------------
void Vector2::RotateRadians( float radians )
{
	float length = CalcLength();
	float headingInRadians = CalcHeadingRadians();

	headingInRadians += radians;

	x = length * cos( headingInRadians );
	y = length * sin( headingInRadians );
}
Beispiel #7
0
///---------------------------------------------------------------------------------
/// very slow
///---------------------------------------------------------------------------------
float Vector2::SetLength( float newLength )
{

	float oldLength = CalcLength();
	Normalize();

	x *= newLength;
	y *= newLength;
	return oldLength; 
}
Beispiel #8
0
///---------------------------------------------------------------------------------
/// very slow
///---------------------------------------------------------------------------------
void Vector2::RotateDegrees( float degrees )
{
	float length = CalcLength();
	float headingInDegrees = CalcHeadingDegrees();

	headingInDegrees += degrees;
	float headingInRadians = ConvertDegreesToRadians( headingInDegrees );

	x = length * cos( headingInRadians );
	y = length * sin( headingInRadians );
}
nscoord 
nsMathMLmfracFrame::CalcLineThickness(nsPresContext*  aPresContext,
                                      nsStyleContext*  aStyleContext,
                                      nsString&        aThicknessAttribute,
                                      nscoord          onePixel,
                                      nscoord          aDefaultRuleThickness)
{
  nscoord defaultThickness = aDefaultRuleThickness;
  nscoord lineThickness = aDefaultRuleThickness;
  nscoord minimumThickness = onePixel;

  if (!aThicknessAttribute.IsEmpty()) {
    if (aThicknessAttribute.EqualsLiteral("thin")) {
      lineThickness = NSToCoordFloor(defaultThickness * THIN_FRACTION_LINE);
      minimumThickness = onePixel * THIN_FRACTION_LINE_MINIMUM_PIXELS;
      // should visually decrease by at least one pixel, if default is not a pixel
      if (defaultThickness > onePixel && lineThickness > defaultThickness - onePixel)
        lineThickness = defaultThickness - onePixel;
    }
    else if (aThicknessAttribute.EqualsLiteral("medium")) {
      lineThickness = NSToCoordRound(defaultThickness * MEDIUM_FRACTION_LINE);
      minimumThickness = onePixel * MEDIUM_FRACTION_LINE_MINIMUM_PIXELS;
      // should visually increase by at least one pixel
      if (lineThickness < defaultThickness + onePixel)
        lineThickness = defaultThickness + onePixel;
    }
    else if (aThicknessAttribute.EqualsLiteral("thick")) {
      lineThickness = NSToCoordCeil(defaultThickness * THICK_FRACTION_LINE);
      minimumThickness = onePixel * THICK_FRACTION_LINE_MINIMUM_PIXELS;
      // should visually increase by at least two pixels
      if (lineThickness < defaultThickness + 2*onePixel)
        lineThickness = defaultThickness + 2*onePixel;
    }
    else { // see if it is a plain number, or a percentage, or a h/v-unit like 1ex, 2px, 1em
      nsCSSValue cssValue;
      if (ParseNumericValue(aThicknessAttribute, cssValue)) {
        nsCSSUnit unit = cssValue.GetUnit();
        if (eCSSUnit_Number == unit)
          lineThickness = nscoord(float(defaultThickness) * cssValue.GetFloatValue());
        else if (eCSSUnit_Percent == unit)
          lineThickness = nscoord(float(defaultThickness) * cssValue.GetPercentValue());
        else if (eCSSUnit_Null != unit)
          lineThickness = CalcLength(aPresContext, aStyleContext, cssValue);
      }
    }
  }

  // use minimum if the lineThickness is a non-zero value less than minimun
  if (lineThickness && lineThickness < minimumThickness) 
    lineThickness = minimumThickness;

  return lineThickness;
}
Beispiel #10
0
primitiveType Vector4< primitiveType >::SetLength( primitiveType newLength )
{

    primitiveType oldLength = CalcLength();
    Normalize4D();

    x *= newLength;
    y *= newLength;
    z *= newLength;
    w *= newLength;

    return oldLength;
}
void
nsMathMLmpaddedFrame::UpdateValue(int32_t                  aSign,
                                  int32_t                  aPseudoUnit,
                                  const nsCSSValue&        aCSSValue,
                                  const ReflowOutput& aDesiredSize,
                                  nscoord&                 aValueToUpdate,
                                  float                aFontSizeInflation) const
{
  nsCSSUnit unit = aCSSValue.GetUnit();
  if (NS_MATHML_SIGN_INVALID != aSign && eCSSUnit_Null != unit) {
    nscoord scaler = 0, amount = 0;

    if (eCSSUnit_Percent == unit || eCSSUnit_Number == unit) {
      switch(aPseudoUnit) {
        case NS_MATHML_PSEUDO_UNIT_WIDTH:
             scaler = aDesiredSize.Width();
             break;

        case NS_MATHML_PSEUDO_UNIT_HEIGHT:
             scaler = aDesiredSize.BlockStartAscent();
             break;

        case NS_MATHML_PSEUDO_UNIT_DEPTH:
             scaler = aDesiredSize.Height() - aDesiredSize.BlockStartAscent();
             break;

        default:
          // if we ever reach here, it would mean something is wrong 
          // somewhere with the setup and/or the caller
          NS_ERROR("Unexpected Pseudo Unit");
          return;
      }
    }

    if (eCSSUnit_Number == unit)
      amount = NSToCoordRound(float(scaler) * aCSSValue.GetFloatValue());
    else if (eCSSUnit_Percent == unit)
      amount = NSToCoordRound(float(scaler) * aCSSValue.GetPercentValue());
    else
      amount = CalcLength(PresContext(), mStyleContext, aCSSValue,
                          aFontSizeInflation);

    if (NS_MATHML_SIGN_PLUS == aSign)
      aValueToUpdate += amount;
    else if (NS_MATHML_SIGN_MINUS == aSign)
      aValueToUpdate -= amount;
    else
      aValueToUpdate  = amount;
  }
}
void
nsMathMLmpaddedFrame::UpdateValue(PRInt32                  aSign,
                                  PRInt32                  aPseudoUnit,
                                  const nsCSSValue&        aCSSValue,
                                  const nsBoundingMetrics& aBoundingMetrics,
                                  nscoord&                 aValueToUpdate) const
{
  nsCSSUnit unit = aCSSValue.GetUnit();
  if (NS_MATHML_SIGN_INVALID != aSign && eCSSUnit_Null != unit) {
    nscoord scaler = 0, amount = 0;

    if (eCSSUnit_Percent == unit || eCSSUnit_Number == unit) {
      switch(aPseudoUnit) {
        case NS_MATHML_PSEUDO_UNIT_WIDTH:
             scaler = aBoundingMetrics.width;
             break;

        case NS_MATHML_PSEUDO_UNIT_HEIGHT:
             scaler = aBoundingMetrics.ascent;
             break;

        case NS_MATHML_PSEUDO_UNIT_DEPTH:
             scaler = aBoundingMetrics.descent;
             break;

        default:
          // if we ever reach here, it would mean something is wrong 
          // somewhere with the setup and/or the caller
          NS_ERROR("Unexpected Pseudo Unit");
          return;
      }
    }

    if (eCSSUnit_Number == unit)
      amount = NSToCoordRound(float(scaler) * aCSSValue.GetFloatValue());
    else if (eCSSUnit_Percent == unit)
      amount = NSToCoordRound(float(scaler) * aCSSValue.GetPercentValue());
    else
      amount = CalcLength(PresContext(), mStyleContext, aCSSValue);

    nscoord oldValue = aValueToUpdate;
    if (NS_MATHML_SIGN_PLUS == aSign)
      aValueToUpdate += amount;
    else if (NS_MATHML_SIGN_MINUS == aSign)
      aValueToUpdate -= amount;
    else
      aValueToUpdate  = amount;
  }
}
Beispiel #13
0
///---------------------------------------------------------------------------------
/// very slow
///---------------------------------------------------------------------------------
float Vector2::Normalize() 
{
	if( CalcLengthSquared() == 0.0f )
		return 0.0f;

	float length = CalcLength();
	if( length == 0.0f ) 
		return 0.0f;

	float inverseLength = 1.0f / length;
	x *= inverseLength;
	y *= inverseLength;

	return length;
}
Beispiel #14
0
primitiveType Vector4< primitiveType >::Normalize3D()
{
    if( CalcLengthSquared() == (primitiveType) 0 )
        return (primitiveType) 0;

    float length = CalcLength();
    if( length == (primitiveType) 0 )
        return (primitiveType) 0;

    float inverseLength = ( (primitiveType) 1 ) / length;
    x *= inverseLength;
    y *= inverseLength;
    z *= inverseLength;

    return length;
}
Beispiel #15
0
///---------------------------------------------------------------------------------
///
///---------------------------------------------------------------------------------
const Vector2 Vector2::Normalized() const
{
    if (CalcLengthSquared() == 0.0f)
        return Vector2::ZERO;

    float length = CalcLength();
    if (length == 0.0f)
        return Vector2::ZERO;

    Vector2 returnVec;

    float inverseLength = 1.0f / length;
    returnVec.x = x * inverseLength;
    returnVec.y = y * inverseLength;

    return returnVec;
}
Beispiel #16
0
PWCHAR WSTR::New(PWCHAR Source, DWORD Len)
{
	// Функция создаёт строку , копию Source.
	// Len - Количество копируемых символов
	//       если равно 0, то будет скопирована вся строка

	if (Source == NULL) return NULL;

	if (Len == 0) Len = CalcLength(Source);
	if (Len == 0) return NULL;

	PWCHAR Str = Alloc(Len);
	if (Str != NULL)
		m_memcpy(Str, Source, Len * sizeof(WCHAR));

	return Str;

}
void
nsMathMLmpaddedFrame::UpdateValue(PRInt32                  aSign,
                                  PRInt32                  aPseudoUnit,
                                  const nsCSSValue&        aCSSValue,
                                  nscoord                  aLeftSpace,
                                  const nsBoundingMetrics& aBoundingMetrics,
                                  nscoord&                 aValueToUpdate) const
{
  nsCSSUnit unit = aCSSValue.GetUnit();
  if (NS_MATHML_SIGN_INVALID != aSign && eCSSUnit_Null != unit) {
    nscoord scaler = 0, amount = 0;

    if (eCSSUnit_Percent == unit || eCSSUnit_Number == unit) {
      switch(aPseudoUnit) {
        case NS_MATHML_PSEUDO_UNIT_WIDTH:
             scaler = aBoundingMetrics.width;
             break;

        case NS_MATHML_PSEUDO_UNIT_HEIGHT:
             scaler = aBoundingMetrics.ascent;
             break;

        case NS_MATHML_PSEUDO_UNIT_DEPTH:
             scaler = aBoundingMetrics.descent;
             break;

        case NS_MATHML_PSEUDO_UNIT_LSPACE:
             scaler = aLeftSpace;
             break;

        default:
          // if we ever reach here, it would mean something is wrong 
          // somewhere with the setup and/or the caller
          NS_ASSERTION(0, "Unexpected Pseudo Unit");
          return;
      }
    }

    if (eCSSUnit_Number == unit)
      amount = NSToCoordRound(float(scaler) * aCSSValue.GetFloatValue());
    else if (eCSSUnit_Percent == unit)
      amount = NSToCoordRound(float(scaler) * aCSSValue.GetPercentValue());
    else
      amount = CalcLength(PresContext(), mStyleContext, aCSSValue);

    nscoord oldValue = aValueToUpdate;
    if (NS_MATHML_SIGN_PLUS == aSign)
      aValueToUpdate += amount;
    else if (NS_MATHML_SIGN_MINUS == aSign)
      aValueToUpdate -= amount;
    else
      aValueToUpdate  = amount;

    /* The REC says:
    Dimensions that would be positive if the content was rendered normally
    cannot be made negative using <mpadded>; a positive dimension is set 
    to 0 if it would otherwise become negative. Dimensions which are 
    initially 0 can be made negative
    */
    if (0 < oldValue && 0 > aValueToUpdate)
      aValueToUpdate = 0;
  }
}
Beispiel #18
0
void CMine::EditGeoBack() 
{
  vms_vector center,opp_center;
  double x,y,z,radius;
  int i;

/* calculate center of current side */
  center.x = center.y = center.z = 0;
  for (i = 0; i < 4; i++) {
	 int vertnum = Segments (Current ()->segment)->verts [side_vert [Current ()->side][i]];
    center.x += Vertices (vertnum)->x;
    center.y += Vertices (vertnum)->y;
    center.z += Vertices (vertnum)->z;
  }
  center.x /= 4;
  center.y /= 4;
  center.z /= 4;

// calculate center of oppisite current side
  opp_center.x = opp_center.y = opp_center.z = 0;
  for (i = 0; i < 4; i++) {
	 int vertnum = Segments (Current ()->segment)->verts [opp_side_vert [Current ()->side][i]];
    opp_center.x += Vertices (vertnum)->x;
    opp_center.y += Vertices (vertnum)->y;
    opp_center.z += Vertices (vertnum)->z;
  }
  opp_center.x /= 4;
  opp_center.y /= 4;
  opp_center.z /= 4;

// normalize vector
  x = center.x - opp_center.x;
  y = center.y - opp_center.y;
  z = center.z - opp_center.z;

  // make sure distance is positive to prevent
  // cube from turning inside out
#if 1
  // defines line orthogonal to a side at a point
  UINT8 orthog_line [6][4] = {
    {8,6,1,3},
    {0,5,7,2},
    {3,1,6,8},
    {2,7,5,0},
    {4,9,10,11},
    {11,10,9,4}
  };
  CDSegment *seg;
  INT16 point0,point1;
  vms_vector *vector0,*vector1;
  bool ok_to_move;

  ok_to_move = TRUE;
  seg = Segments () + Current ()->segment;
  switch (m_selectMode) {
    case POINT_MODE:
      point0 = line_vert [orthog_line [Current ()->side][Current ()->point]][0];
      point1 = line_vert [orthog_line [Current ()->side][Current ()->point]][1];
      vector0 = Vertices (seg->verts [point0]);
      vector1 = Vertices (seg->verts [point1]);
      if (CalcLength(vector0,vector1) - move_rate < F1_0 / 4) {
	ok_to_move = FALSE;
      }
      break;
    case LINE_MODE:
      for (i=0;i<2;i++) {
	point0 = line_vert [orthog_line [Current ()->side][(Current ()->line+i)%4]][0];
	point1 = line_vert [orthog_line [Current ()->side][(Current ()->line+i)%4]][1];
	vector0 = Vertices (seg->verts [point0]);
	vector1 = Vertices (seg->verts [point1]);
	if (CalcLength(vector0,vector1) - move_rate < F1_0 / 4) {
	  ok_to_move = FALSE;
	}
      }
      break;
    case SIDE_MODE:
      for (i = 0; i < 4; i++) {
	point0 = line_vert [orthog_line [Current ()->side][i]][0];
	point1 = line_vert [orthog_line [Current ()->side][i]][1];
	vector0 = Vertices (seg->verts [point0]);
	vector1 = Vertices (seg->verts [point1]);
	if (CalcLength(vector0,vector1) - move_rate < F1_0 / 4) {
	  ok_to_move = FALSE;
	}
      }
      break;
  }
  if (ok_to_move == FALSE) {
    ErrorMsg("Too small to move in that direction");
    return;
  }
#endif

  radius = sqrt(x*x + y*y + z*z);
  if ((radius-move_rate) < F1_0 / 4) {
    if (m_selectMode == POINT_MODE
	|| m_selectMode == LINE_MODE
	|| m_selectMode == SIDE_MODE) {
      ErrorMsg("Cannot make cube any smaller\n"
	       "Cube must be greater or equal to 1.0 units wide.");
    }
  } else {

    // normalize direction
    if (radius > (F1_0/10)) {
      x /= radius;
      y /= radius;
      z /= radius;
    } else {
      vms_vector direction;
      CalcOrthoVector(direction,Current ()->segment,Current ()->side);
      x = (double)direction.x/(double)F1_0;
      y = (double)direction.y/(double)F1_0;
      z = (double)direction.z/(double)F1_0;
    }

// move on x, y, and z
	 theApp.SetModified (TRUE);
	 theApp.LockUndo ();
    MoveOn('X',(INT32) (-x*move_rate));
    MoveOn('Y',(INT32) (-y*move_rate));
    MoveOn('Z',(INT32) (-z*move_rate));
	 theApp.UnlockUndo ();
  }
theApp.SetModified (TRUE);
}
Beispiel #19
0
void CMine::MovePoints(int pt0, int pt1) 
{
	vms_vector *vector0,*vector1,delta;
	int point0,point1;
	double length;
	int point;
	int i;
	vms_vector *vect;

point0  = side_vert [Current ()->side][CURRENT_POINT(pt0)];
point1  = side_vert [Current ()->side][CURRENT_POINT(pt1)];
vector0 = Vertices (Segments (Current ()->segment)->verts [point0]);
vector1 = Vertices (Segments (Current ()->segment)->verts [point1]);
length  = CalcLength(vector0,vector1);
if (length >= F1_0) {
	delta.x = (FIX)(((double)(vector1->x - vector0->x) * (double)move_rate)/length);
	delta.y = (FIX)(((double)(vector1->y - vector0->y) * (double)move_rate)/length);
	delta.z = (FIX)(((double)(vector1->z - vector0->z) * (double)move_rate)/length);
	} 
else {
	delta.x = move_rate;
	delta.y = 0;
	delta.z = 0;
	}

switch (m_selectMode){
	case POINT_MODE:
		point = side_vert [Current ()->side][CURRENT_POINT(0)];
		vect  = Vertices (Segments (Current ()->segment)->verts [point]);
		vect->x += delta.x;
		vect->y += delta.y;
		vect->z += delta.z;
		theApp.SetModified (TRUE);
		break;

	case LINE_MODE:
		point = side_vert [Current ()->side][CURRENT_POINT(0)];
		vect  = Vertices (Segments (Current ()->segment)->verts [point]);
		vect->x += delta.x;
		vect->y += delta.y;
		vect->z += delta.z;
		point = side_vert [Current ()->side][CURRENT_POINT(1)];
		vect  = Vertices (Segments (Current ()->segment)->verts [point]);
		vect->x += delta.x;
		vect->y += delta.y;
		vect->z += delta.z;
		theApp.SetModified (TRUE);
		break;

	case SIDE_MODE:
		for (i = 0; i < 4; i++) {
			point = side_vert [Current ()->side][i];
			vect  = Vertices (Segments (Current ()->segment)->verts [point]);
			vect->x += delta.x;
			vect->y += delta.y;
			vect->z += delta.z;
			}
		theApp.SetModified (TRUE);
		break;

	case CUBE_MODE:
		for (i = 0; i < 8; i++) {
			vect = Vertices (Segments (Current ()->segment)->verts [i]);
			vect->x += delta.x;
			vect->y += delta.y;
			vect->z += delta.z;
			}
		theApp.SetModified (TRUE);
		break;

	case OBJECT_MODE:
		CurrObj ()->pos.x += delta.x;
		CurrObj ()->pos.y += delta.y;
		CurrObj ()->pos.z += delta.z;
		theApp.SetModified (TRUE);
		break;

	case BLOCK_MODE:
		bool bMoved = false;
		for (i = 0; i < MAX_VERTICES; i++) {
			if (*VertStatus (i) & MARKED_MASK) {
				Vertices (i)->x += delta.x;
				Vertices (i)->y += delta.y;
				Vertices (i)->z += delta.z;
				bMoved = true;
				}
			}
		theApp.SetModified (bMoved);
		break;
	}
}
Beispiel #20
0
bool CMine::CalcSideLights (int segnum, int sidenum, vms_vector& source_center, 
									 vms_vector *source_corner, vms_vector& A, double *effect,
									 double fLightScale, bool bIgnoreAngle)
{
	CDSegment *seg = Segments (segnum);
// calculate vector between center of source segment and center of child
vms_vector B,center;
CalcCenter (center,segnum,sidenum);
B.x = center.x - source_center.x;
B.y = center.y - source_center.y;
B.z = center.z - source_center.z;

// calculate angle between vectors (use dot product equation)
if (!bIgnoreAngle) {
	double ratio,angle;
	double A_dot_B = (double)A.x * (double)B.x
						+ (double)A.y * (double)B.y
						+ (double)A.z * (double)B.z;
	double mag_A = my_sqrt( (double)A.x*(double)A.x
						+(double)A.y*(double)A.y
						+(double)A.z*(double)A.z);
	double mag_B = my_sqrt( (double)B.x*(double)B.x
						+(double)B.y*(double)B.y
						+(double)B.z*(double)B.z);
	if (mag_A == 0 || mag_B == 0)
		angle = (200.0 * M_PI)/180.0; // force a failure
	else {
		ratio = A_dot_B/(mag_A * mag_B);
		ratio = ((double)((int)(ratio*1000.0))) / 1000.0;
		if (ratio < -1.0 || ratio > (double)1.0)
			angle = (199.0 * M_PI)/180.0;  // force a failure
		else
			angle = acos(ratio);
		}
	// if angle is less than 110 degrees
	// then we found a match
	if (angle >= (180.0 * M_PI)/180.0)
		return false;
	}
int i, j;
for (j = 0; j < 4; j++) {
	vms_vector corner;
	int vertnum = side_vert[sidenum][j];
	int h = seg->verts[vertnum];
	corner.x = Vertices (h)->x;
	corner.y = Vertices (h)->y;
	corner.z = Vertices (h)->z;
	double length = 20.0 * m_lightRenderDepth;
	for (i = 0; i < 4; i++)
		length = min (length, CalcLength (source_corner + i, &corner) / F1_0);
	length /= 10.0 * m_lightRenderDepth / 6.0; // divide by 1/2 a cubes length so opposite side
	// light is recuded by 1/4
	effect [j] = 32;
	if (length > 1.0)//if (length < 20.0 * m_lightRenderDepth) // (roughly 4 standard cube lengths)
		effect [j] /= (length * length);
	effect [j] *= fLightScale;
//	else
//		effect [j] = 0;
	}
// if any of the effects are > 0, then increment the
// light for that side
return (effect [0] != 0 || effect [1] != 0 || effect [2] != 0 || effect [3] != 0);
}
// get our 'form' and lookup in the Operator Dictionary to fetch 
// our default data that may come from there. Then complete our setup
// using attributes that we may have. To stay in sync, this function is
// called very often. We depend on many things that may change around us.
// However, we re-use unchanged values.
void
nsMathMLmoFrame::ProcessOperatorData()
{
  // if we have been here before, we will just use our cached form
  nsOperatorFlags form = NS_MATHML_OPERATOR_GET_FORM(mFlags);
  nsAutoString value;

  // special bits are always kept in mFlags.
  // remember the mutable bit from ProcessTextData().
  // Some chars are listed under different forms in the dictionary,
  // and there could be a form under which the char is mutable.
  // If the char is the core of an embellished container, we will keep
  // it mutable irrespective of the form of the embellished container.
  // Also remember the other special bits that we want to carry forward.
  mFlags &= NS_MATHML_OPERATOR_MUTABLE |
            NS_MATHML_OPERATOR_ACCENT | 
            NS_MATHML_OPERATOR_MOVABLELIMITS |
            NS_MATHML_OPERATOR_CENTERED |
            NS_MATHML_OPERATOR_INVISIBLE;

  if (!mEmbellishData.coreFrame) {
    // i.e., we haven't been here before, the default form is infix
    form = NS_MATHML_OPERATOR_FORM_INFIX;

    // reset everything so that we don't keep outdated values around
    // in case of dynamic changes
    mEmbellishData.flags = 0;
    mEmbellishData.coreFrame = nullptr;
    mEmbellishData.leadingSpace = 0;
    mEmbellishData.trailingSpace = 0;
    if (mMathMLChar.Length() != 1)
      mEmbellishData.direction = NS_STRETCH_DIRECTION_UNSUPPORTED;  
    // else... retain the native direction obtained in ProcessTextData()

    if (!mFrames.FirstChild()) {
      return;
    }

    mEmbellishData.flags |= NS_MATHML_EMBELLISH_OPERATOR;
    mEmbellishData.coreFrame = this;

    // there are two particular things that we also need to record so that if our
    // parent is <mover>, <munder>, or <munderover>, they will treat us properly:
    // 1) do we have accent="true"
    // 2) do we have movablelimits="true"

    // they need the extra information to decide how to treat their scripts/limits
    // (note: <mover>, <munder>, or <munderover> need not necessarily be our
    // direct parent -- case of embellished operators)

    // default values from the Operator Dictionary were obtained in ProcessTextData()
    // and these special bits are always kept in mFlags
    if (NS_MATHML_OPERATOR_IS_ACCENT(mFlags))
      mEmbellishData.flags |= NS_MATHML_EMBELLISH_ACCENT;
    if (NS_MATHML_OPERATOR_IS_MOVABLELIMITS(mFlags))
      mEmbellishData.flags |= NS_MATHML_EMBELLISH_MOVABLELIMITS;

    // see if the accent attribute is there
    GetAttribute(mContent, mPresentationData.mstyle, nsGkAtoms::accent_,
                 value);
    if (value.EqualsLiteral("true"))
      mEmbellishData.flags |= NS_MATHML_EMBELLISH_ACCENT;
    else if (value.EqualsLiteral("false"))
      mEmbellishData.flags &= ~NS_MATHML_EMBELLISH_ACCENT;

    // see if the movablelimits attribute is there
    GetAttribute(mContent, mPresentationData.mstyle,
                 nsGkAtoms::movablelimits_, value);
    if (value.EqualsLiteral("true"))
      mEmbellishData.flags |= NS_MATHML_EMBELLISH_MOVABLELIMITS;
    else if (value.EqualsLiteral("false"))
      mEmbellishData.flags &= ~NS_MATHML_EMBELLISH_MOVABLELIMITS;

     // ---------------------------------------------------------------------
     // we will be called again to re-sync the rest of our state next time...
     // (nobody needs the other values below at this stage)
     mFlags |= form;
     return;
  }

  nsPresContext* presContext = PresContext();

  // beware of bug 133814 - there is a two-way dependency in the
  // embellished hierarchy: our embellished ancestors need to set
  // their flags based on some of our state (set above), and here we
  // need to re-sync our 'form' depending on our outermost embellished
  // container. A null form here means that an earlier attempt to stretch
  // our mMathMLChar failed, in which case we don't bother re-stretching again
  if (form) {
    // get our outermost embellished container and its parent. 
    // (we ensure that we are the core, not just a sibling of the core)
    nsIFrame* embellishAncestor = this;
    nsEmbellishData embellishData;
    nsIFrame* parentAncestor = this;
    do {
      embellishAncestor = parentAncestor;
      parentAncestor = embellishAncestor->GetParent();
      GetEmbellishDataFrom(parentAncestor, embellishData);
    } while (embellishData.coreFrame == this);

    // flag if we have an embellished ancestor
    if (embellishAncestor != this)
      mFlags |= NS_MATHML_OPERATOR_EMBELLISH_ANCESTOR;
    else
      mFlags &= ~NS_MATHML_OPERATOR_EMBELLISH_ANCESTOR;

    // find the position of our outermost embellished container w.r.t
    // its siblings.

    nsIFrame* nextSibling = embellishAncestor->GetNextSibling();
    nsIFrame* prevSibling = embellishAncestor->GetPrevSibling();

    // flag to distinguish from a real infix
    if (!prevSibling && !nextSibling)
      mFlags |= NS_MATHML_OPERATOR_EMBELLISH_ISOLATED;
    else
      mFlags &= ~NS_MATHML_OPERATOR_EMBELLISH_ISOLATED;

    // find our form
    form = NS_MATHML_OPERATOR_FORM_INFIX;
    GetAttribute(mContent, mPresentationData.mstyle, nsGkAtoms::form,
                 value);
    if (!value.IsEmpty()) {
      if (value.EqualsLiteral("prefix"))
        form = NS_MATHML_OPERATOR_FORM_PREFIX;
      else if (value.EqualsLiteral("postfix"))
        form = NS_MATHML_OPERATOR_FORM_POSTFIX;
    }
    else {
      // set our form flag depending on the position
      if (!prevSibling && nextSibling)
        form = NS_MATHML_OPERATOR_FORM_PREFIX;
      else if (prevSibling && !nextSibling)
        form = NS_MATHML_OPERATOR_FORM_POSTFIX;
    }
    mFlags &= ~NS_MATHML_OPERATOR_FORM; // clear the old form bits
    mFlags |= form;

    // Use the default value suggested by the MathML REC.
    // http://www.w3.org/TR/MathML/chapter3.html#presm.mo.attrs
    // thickmathspace = 5/18em
    float lspace = 5.0f/18.0f;
    float rspace = 5.0f/18.0f;
    if (NS_MATHML_OPERATOR_IS_INVISIBLE(mFlags)) {
      // mMathMLChar has been reset in ProcessTextData so we can not find it
      // in the operator dictionary. The operator dictionary always uses
      // lspace = rspace = 0 for invisible operators.
      lspace = rspace = 0;
    } else {
      // lookup the operator dictionary
      nsAutoString data;
      mMathMLChar.GetData(data);
      nsMathMLOperators::LookupOperator(data, form, &mFlags, &lspace, &rspace);
    }
    if (lspace || rspace) {
      // Cache the default values of lspace and rspace.
      // since these values are relative to the 'em' unit, convert to twips now
      nscoord em;
      nsRefPtr<nsFontMetrics> fm;
      nsLayoutUtils::GetFontMetricsForFrame(this, getter_AddRefs(fm));
      GetEmHeight(fm, em);

      mEmbellishData.leadingSpace = NSToCoordRound(lspace * em);
      mEmbellishData.trailingSpace = NSToCoordRound(rspace * em);

      // tuning if we don't want too much extra space when we are a script.
      // (with its fonts, TeX sets lspace=0 & rspace=0 as soon as scriptlevel>0.
      // Our fonts can be anything, so...)
      if (StyleFont()->mScriptLevel > 0) {
        if (NS_MATHML_OPERATOR_EMBELLISH_IS_ISOLATED(mFlags)) {
          // could be an isolated accent or script, e.g., x^{+}, just zero out
          mEmbellishData.leadingSpace = 0;
          mEmbellishData.trailingSpace  = 0;
        }
        else if (!NS_MATHML_OPERATOR_HAS_EMBELLISH_ANCESTOR(mFlags)) {
          mEmbellishData.leadingSpace /= 2;
          mEmbellishData.trailingSpace  /= 2;
        }
      }
    }
  }

  // If we are an accent without explicit lspace="." or rspace=".",
  // we will ignore our default leading/trailing space

  // lspace
  //
  // "Specifies the leading space appearing before the operator"
  //
  // values: length
  // default: set by dictionary (thickmathspace) 
  //
  // XXXfredw Support for negative and relative values is not implemented
  // (bug 805926).
  // Relative values will give a multiple of the current leading space,
  // which is not necessarily the default one.
  //
  nscoord leadingSpace = mEmbellishData.leadingSpace;
  GetAttribute(mContent, mPresentationData.mstyle, nsGkAtoms::lspace_,
               value);
  if (!value.IsEmpty()) {
    nsCSSValue cssValue;
    if (nsMathMLElement::ParseNumericValue(value, cssValue, 0,
                                           mContent->OwnerDoc())) {
      if ((eCSSUnit_Number == cssValue.GetUnit()) && !cssValue.GetFloatValue())
        leadingSpace = 0;
      else if (cssValue.IsLengthUnit())
        leadingSpace = CalcLength(presContext, mStyleContext, cssValue);
      mFlags |= NS_MATHML_OPERATOR_LSPACE_ATTR;
    }
  }

  // rspace
  //
  // "Specifies the trailing space appearing after the operator"
  //
  // values: length
  // default: set by dictionary (thickmathspace) 
  //
  // XXXfredw Support for negative and relative values is not implemented
  // (bug 805926).
  // Relative values will give a multiple of the current leading space,
  // which is not necessarily the default one.
  //
  nscoord trailingSpace = mEmbellishData.trailingSpace;
  GetAttribute(mContent, mPresentationData.mstyle, nsGkAtoms::rspace_,
               value);
  if (!value.IsEmpty()) {
    nsCSSValue cssValue;
    if (nsMathMLElement::ParseNumericValue(value, cssValue, 0,
                                           mContent->OwnerDoc())) {
      if ((eCSSUnit_Number == cssValue.GetUnit()) && !cssValue.GetFloatValue())
        trailingSpace = 0;
      else if (cssValue.IsLengthUnit())
        trailingSpace = CalcLength(presContext, mStyleContext, cssValue);
      mFlags |= NS_MATHML_OPERATOR_RSPACE_ATTR;
    }
  }

  // little extra tuning to round lspace & rspace to at least a pixel so that
  // operators don't look as if they are colliding with their operands
  if (leadingSpace || trailingSpace) {
    nscoord onePixel = nsPresContext::CSSPixelsToAppUnits(1);
    if (leadingSpace && leadingSpace < onePixel)
      leadingSpace = onePixel;
    if (trailingSpace && trailingSpace < onePixel)
      trailingSpace = onePixel;
  }

  // the values that we get from our attributes override the dictionary
  mEmbellishData.leadingSpace = leadingSpace;
  mEmbellishData.trailingSpace = trailingSpace;

  // Now see if there are user-defined attributes that override the dictionary.
  // XXX If an attribute can be forced to be true when it is false in the
  // dictionary, then the following code has to change...

  // For each attribute overriden by the user, turn off its bit flag.
  // symmetric|movablelimits|separator|largeop|accent|fence|stretchy|form
  // special: accent and movablelimits are handled above,
  // don't process them here

  GetAttribute(mContent, mPresentationData.mstyle,
               nsGkAtoms::stretchy_, value);
  if (value.EqualsLiteral("false")) {
    mFlags &= ~NS_MATHML_OPERATOR_STRETCHY;
  } else if (value.EqualsLiteral("true")) {
    mFlags |= NS_MATHML_OPERATOR_STRETCHY;
  }
  if (NS_MATHML_OPERATOR_IS_FENCE(mFlags)) {
    GetAttribute(mContent, mPresentationData.mstyle,
                 nsGkAtoms::fence_, value);
    if (value.EqualsLiteral("false"))
      mFlags &= ~NS_MATHML_OPERATOR_FENCE;
  }
  GetAttribute(mContent, mPresentationData.mstyle,
               nsGkAtoms::largeop_, value);
  if (value.EqualsLiteral("false")) {
    mFlags &= ~NS_MATHML_OPERATOR_LARGEOP;
  } else if (value.EqualsLiteral("true")) {
    mFlags |= NS_MATHML_OPERATOR_LARGEOP;
  }
  if (NS_MATHML_OPERATOR_IS_SEPARATOR(mFlags)) {
    GetAttribute(mContent, mPresentationData.mstyle,
                 nsGkAtoms::separator_, value);
    if (value.EqualsLiteral("false"))
      mFlags &= ~NS_MATHML_OPERATOR_SEPARATOR;
  }
  GetAttribute(mContent, mPresentationData.mstyle, nsGkAtoms::symmetric_,
               value);
  if (value.EqualsLiteral("false"))
    mFlags &= ~NS_MATHML_OPERATOR_SYMMETRIC;
  else if (value.EqualsLiteral("true"))
    mFlags |= NS_MATHML_OPERATOR_SYMMETRIC;


  // minsize
  //
  // "Specifies the minimum size of the operator when stretchy"
  //
  // values: length
  // default: set by dictionary (1em)
  //
  // We don't allow negative values.
  // Note: Contrary to other "length" values, unitless and percentage do not
  // give a multiple of the defaut value but a multiple of the operator at
  // normal size.
  //
  mMinSize = 0;
  GetAttribute(mContent, mPresentationData.mstyle, nsGkAtoms::minsize_,
               value);
  if (!value.IsEmpty()) {
    nsCSSValue cssValue;
    if (nsMathMLElement::ParseNumericValue(value, cssValue,
                                           nsMathMLElement::
                                           PARSE_ALLOW_UNITLESS,
                                           mContent->OwnerDoc())) {
      nsCSSUnit unit = cssValue.GetUnit();
      if (eCSSUnit_Number == unit)
        mMinSize = cssValue.GetFloatValue();
      else if (eCSSUnit_Percent == unit)
        mMinSize = cssValue.GetPercentValue();
      else if (eCSSUnit_Null != unit) {
        mMinSize = float(CalcLength(presContext, mStyleContext, cssValue));
        mFlags |= NS_MATHML_OPERATOR_MINSIZE_ABSOLUTE;
      }
    }
  }

  // maxsize
  //
  // "Specifies the maximum size of the operator when stretchy"
  //
  // values: length | "infinity"
  // default: set by dictionary (infinity)
  //
  // We don't allow negative values.
  // Note: Contrary to other "length" values, unitless and percentage do not
  // give a multiple of the defaut value but a multiple of the operator at
  // normal size.
  //
  mMaxSize = NS_MATHML_OPERATOR_SIZE_INFINITY;
  GetAttribute(mContent, mPresentationData.mstyle, nsGkAtoms::maxsize_,
               value);
  if (!value.IsEmpty()) {
    nsCSSValue cssValue;
    if (nsMathMLElement::ParseNumericValue(value, cssValue,
                                           nsMathMLElement::
                                           PARSE_ALLOW_UNITLESS,
                                           mContent->OwnerDoc())) {
      nsCSSUnit unit = cssValue.GetUnit();
      if (eCSSUnit_Number == unit)
        mMaxSize = cssValue.GetFloatValue();
      else if (eCSSUnit_Percent == unit)
        mMaxSize = cssValue.GetPercentValue();
      else if (eCSSUnit_Null != unit) {
        mMaxSize = float(CalcLength(presContext, mStyleContext, cssValue));
        mFlags |= NS_MATHML_OPERATOR_MAXSIZE_ABSOLUTE;
      }
    }
  }
}
Beispiel #22
0
bool MmlParser::FeedChar(int ch)
{
	bool continueFlag;
	if ('a' <= ch && ch <= 'z') ch = ch - 'a' + 'A';
	do {
		continueFlag = false;
		if (_stat == STAT_Begin) {
			if (IsEOD(ch)) {
				// nothing to do
			} else if ('A' <= ch && ch <= 'G') {
				_operator = ch;
				_operatorSub = '\0';
				_numAccum = 0;
				_cntDot = 0;
				_stat = STAT_Note;
			} else if (ch == 'R') {
				_operator = ch;
				_numAccum = 0;
				_cntDot = 0;
				_stat = STAT_RestLengthPre;
			} else if (ch == '&') {
				_operator = ch;
			} else if (ch == 'O') {
				_operator = ch;
				_numAccum = 0;
				_stat = STAT_OctavePre;
			} else if (ch == '>') {
				_operator = ch;
				if (_octave < 255) _octave++;
			} else if (ch == '<') {
				_operator = ch;
				if (_octave > 0) _octave--;
			} else if (ch == 'L') {
				_operator = ch;
				_numAccum = 0;
				_cntDot = 0;
				_stat = STAT_LengthPre;
			} else if (ch == 'V') {
				_operator = ch;
				_numAccum = 0;
				_stat = STAT_VolumePre;
			} else if (ch == '@') {
				_operator = ch;
				_numAccum = 0;
				_stat = STAT_TonePre;
			} else if (ch == 'T') {
				_operator = ch;
				_numAccum = 0;
				_stat = STAT_TempoPre;
			} else {
				// nothing to do
			}
		} else if (_stat == STAT_Note) {		// -------- Note --------
			if (ch == '#' || ch == '+' || ch == '-') {
				_operatorSub = ch;
				_stat = STAT_NoteLengthPre;
			} else if (IsDigit(ch)) {
				continueFlag = true;
				_stat = STAT_NoteLength;
			} else if (IsWhite(ch)) {
				// nothing to do
			} else {
				continueFlag = true;
				_stat = STAT_NoteFix;
			}
		} else if (_stat == STAT_NoteLengthPre) {
			if (IsDigit(ch)) {
				continueFlag = true;
				_stat = STAT_NoteLength;
			} else if (IsWhite(ch)) {
				// nothing to do
			} else {
				continueFlag = true;
				_stat = STAT_NoteFix;
			}
		} else if (_stat == STAT_NoteLength) {
			if (IsDigit(ch)) {
				_numAccum = _numAccum * 10 + (ch - '0');
			} else if (ch == '.') {
				_cntDot++;
			} else {
				continueFlag = true;
				_stat = STAT_NoteFix;
			}
		} else if (_stat == STAT_NoteFix) {
			static const unsigned char noteTbl[] = {
				9, 11, 0, 2, 4, 5, 7,
			};
			unsigned char note = noteTbl[_operator - 'A'] + _octave * 12;
			if (_operatorSub == '#' || _operatorSub == '+') {
				if (note < 127) note++;
			} else if (_operatorSub == '-') {
				if (note > 0) note--;
			} else {
				// nothing to do
			}
			int length = CalcLength(_numAccum, _cntDot, _lengthDefault);
			_handler.MmlNote(*this, note, length);
			continueFlag = true;
			_stat = STAT_Begin;
		} else if (_stat == STAT_RestLengthPre) {// -------- Rest --------
			if (IsDigit(ch)) {
				continueFlag = true;
				_stat = STAT_RestLength;
			} else if (IsWhite(ch)) {
				// nothing to do
			} else {
				continueFlag = true;
				_stat = STAT_RestFix;
			}
		} else if (_stat == STAT_RestLength) {
			if (IsDigit(ch)) {
				_numAccum = _numAccum * 10 + (ch - '0');
			} else if (ch == '.') {
				_cntDot++;
			} else {
				continueFlag = true;
				_stat = STAT_RestFix;
			}
		} else if (_stat == STAT_RestFix) {
			int length = CalcLength(_numAccum, _cntDot, _lengthDefault);
			_handler.MmlRest(*this, length);
			continueFlag = true;
			_stat = STAT_Begin;
		} else if (_stat == STAT_OctavePre) {	// -------- Octave --------
			if (IsDigit(ch)) {
				continueFlag = true;
				_stat = STAT_Octave;
			} else if (IsWhite(ch)) {
				// nothing to do
			} else {
				continueFlag = true;
				_stat = STAT_OctaveFix;
			}
		} else if (_stat == STAT_Octave) {
			if (IsDigit(ch)) {
				_numAccum = _numAccum * 10 + (ch - '0');
			} else {
				continueFlag = true;
				_stat = STAT_OctaveFix;
			}
		} else if (_stat == STAT_OctaveFix) {
			_octave = _numAccum;
			continueFlag = true;
			_stat = STAT_Begin;
		} else if (_stat == STAT_LengthPre) {	// -------- Length --------
			if (IsDigit(ch)) {
				continueFlag = true;
				_stat = STAT_Length;
			} else if (IsWhite(ch)) {
				// nothing to do
			} else {
				continueFlag = true;
				_stat = STAT_LengthFix;
			}
		} else if (_stat == STAT_Length) {
			if (IsDigit(ch)) {
				_numAccum = _numAccum * 10 + (ch - '0');
			} else if (ch == '.') {
				_cntDot++;
			} else {
				continueFlag = true;
				_stat = STAT_LengthFix;
			}
		} else if (_stat == STAT_LengthFix) {
			_lengthDefault = CalcLength(_numAccum, _cntDot, _lengthDefault);
			continueFlag = true;
			_stat = STAT_Begin;
		} else if (_stat == STAT_VolumePre) {	// -------- Volume --------
			if (IsDigit(ch)) {
				continueFlag = true;
				_stat = STAT_Volume;
			} else if (IsWhite(ch)) {
				// nothing to do
			} else {
				continueFlag = true;
				_stat = STAT_VolumeFix;
			}
		} else if (_stat == STAT_Volume) {
			if (IsDigit(ch)) {
				_numAccum = _numAccum * 10 + (ch - '0');
			} else {
				continueFlag = true;
				_stat = STAT_VolumeFix;
			}
		} else if (_stat == STAT_VolumeFix) {
			_volume = _numAccum;
			continueFlag = true;
			_stat = STAT_Begin;
		} else if (_stat == STAT_TonePre) {		// ------- Tone --------
			if (IsDigit(ch)) {
				continueFlag = true;
				_stat = STAT_Tone;
			} else if (IsWhite(ch)) {
				// nothing to do
			} else {
				continueFlag = true;
				_stat = STAT_ToneFix;
			}
		} else if (_stat == STAT_Tone) {
			if (IsDigit(ch)) {
				_numAccum = _numAccum * 10 + (ch - '0');
			} else {
				continueFlag = true;
				_stat = STAT_ToneFix;
			}
		} else if (_stat == STAT_ToneFix) {
			_tone = _numAccum;
			continueFlag = true;
			_stat = STAT_Begin;
		} else if (_stat == STAT_TempoPre) {	// -------- Tempo --------
			if (IsDigit(ch)) {
				continueFlag = true;
				_stat = STAT_Tempo;
			} else if (IsWhite(ch)) {
				// nothing to do
			} else {
				continueFlag = true;
				_stat = STAT_TempoFix;
			}
		} else if (_stat == STAT_Tempo) {
			if (IsDigit(ch)) {
				_numAccum = _numAccum * 10 + (ch - '0');
			} else {
				continueFlag = true;
				_stat = STAT_TempoFix;
			}
		} else if (_stat == STAT_TempoFix) {
			_tempo = _numAccum;
			continueFlag = true;
			_stat = STAT_Begin;
		}
	} while (continueFlag);
	return true;
}