forked from mirrors/gecko-dev
		
	We have more readable and faster versions (that just omit the namespace arg). Mostly done via sed, with a couple helpers to use the faster lookups where possible. Differential Revision: https://phabricator.services.mozilla.com/D181795
		
			
				
	
	
		
			441 lines
		
	
	
	
		
			16 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			441 lines
		
	
	
	
		
			16 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 | 
						|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 | 
						|
/* This Source Code Form is subject to the terms of the Mozilla Public
 | 
						|
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
						|
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 | 
						|
 | 
						|
#include "nsMathMLmpaddedFrame.h"
 | 
						|
 | 
						|
#include "mozilla/dom/MathMLElement.h"
 | 
						|
#include "mozilla/gfx/2D.h"
 | 
						|
#include "mozilla/PresShell.h"
 | 
						|
#include "mozilla/TextUtils.h"
 | 
						|
#include "nsLayoutUtils.h"
 | 
						|
#include <algorithm>
 | 
						|
 | 
						|
using namespace mozilla;
 | 
						|
 | 
						|
//
 | 
						|
// <mpadded> -- adjust space around content - implementation
 | 
						|
//
 | 
						|
 | 
						|
#define NS_MATHML_SIGN_INVALID -1  // if the attribute is not there
 | 
						|
#define NS_MATHML_SIGN_UNSPECIFIED 0
 | 
						|
#define NS_MATHML_SIGN_MINUS 1
 | 
						|
#define NS_MATHML_SIGN_PLUS 2
 | 
						|
 | 
						|
#define NS_MATHML_PSEUDO_UNIT_UNSPECIFIED 0
 | 
						|
#define NS_MATHML_PSEUDO_UNIT_ITSELF 1  // special
 | 
						|
#define NS_MATHML_PSEUDO_UNIT_WIDTH 2
 | 
						|
#define NS_MATHML_PSEUDO_UNIT_HEIGHT 3
 | 
						|
#define NS_MATHML_PSEUDO_UNIT_DEPTH 4
 | 
						|
#define NS_MATHML_PSEUDO_UNIT_NAMEDSPACE 5
 | 
						|
 | 
						|
nsIFrame* NS_NewMathMLmpaddedFrame(PresShell* aPresShell,
 | 
						|
                                   ComputedStyle* aStyle) {
 | 
						|
  return new (aPresShell)
 | 
						|
      nsMathMLmpaddedFrame(aStyle, aPresShell->GetPresContext());
 | 
						|
}
 | 
						|
 | 
						|
NS_IMPL_FRAMEARENA_HELPERS(nsMathMLmpaddedFrame)
 | 
						|
 | 
						|
nsMathMLmpaddedFrame::~nsMathMLmpaddedFrame() = default;
 | 
						|
 | 
						|
NS_IMETHODIMP
 | 
						|
nsMathMLmpaddedFrame::InheritAutomaticData(nsIFrame* aParent) {
 | 
						|
  // let the base class get the default from our parent
 | 
						|
  nsMathMLContainerFrame::InheritAutomaticData(aParent);
 | 
						|
 | 
						|
  mPresentationData.flags |= NS_MATHML_STRETCH_ALL_CHILDREN_VERTICALLY;
 | 
						|
 | 
						|
  return NS_OK;
 | 
						|
}
 | 
						|
 | 
						|
void nsMathMLmpaddedFrame::ProcessAttributes() {
 | 
						|
  // clang-format off
 | 
						|
  /*
 | 
						|
  parse the attributes
 | 
						|
 | 
						|
  width  = [+|-] unsigned-number (% [pseudo-unit] | pseudo-unit | h-unit | namedspace)
 | 
						|
  height = [+|-] unsigned-number (% [pseudo-unit] | pseudo-unit | v-unit | namedspace)
 | 
						|
  depth  = [+|-] unsigned-number (% [pseudo-unit] | pseudo-unit | v-unit | namedspace)
 | 
						|
  lspace = [+|-] unsigned-number (% [pseudo-unit] | pseudo-unit | h-unit | namedspace)
 | 
						|
  voffset= [+|-] unsigned-number (% [pseudo-unit] | pseudo-unit | v-unit | namedspace)
 | 
						|
  */
 | 
						|
  // clang-format on
 | 
						|
 | 
						|
  nsAutoString value;
 | 
						|
 | 
						|
  // width
 | 
						|
  mWidthSign = NS_MATHML_SIGN_INVALID;
 | 
						|
  mContent->AsElement()->GetAttr(nsGkAtoms::width, value);
 | 
						|
  if (!value.IsEmpty()) {
 | 
						|
    if (!ParseAttribute(value, mWidthSign, mWidth, mWidthPseudoUnit)) {
 | 
						|
      ReportParseError(nsGkAtoms::width->GetUTF16String(), value.get());
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  // height
 | 
						|
  mHeightSign = NS_MATHML_SIGN_INVALID;
 | 
						|
  mContent->AsElement()->GetAttr(nsGkAtoms::height, value);
 | 
						|
  if (!value.IsEmpty()) {
 | 
						|
    if (!ParseAttribute(value, mHeightSign, mHeight, mHeightPseudoUnit)) {
 | 
						|
      ReportParseError(nsGkAtoms::height->GetUTF16String(), value.get());
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  // depth
 | 
						|
  mDepthSign = NS_MATHML_SIGN_INVALID;
 | 
						|
  mContent->AsElement()->GetAttr(nsGkAtoms::depth_, value);
 | 
						|
  if (!value.IsEmpty()) {
 | 
						|
    if (!ParseAttribute(value, mDepthSign, mDepth, mDepthPseudoUnit)) {
 | 
						|
      ReportParseError(nsGkAtoms::depth_->GetUTF16String(), value.get());
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  // lspace
 | 
						|
  mLeadingSpaceSign = NS_MATHML_SIGN_INVALID;
 | 
						|
  mContent->AsElement()->GetAttr(nsGkAtoms::lspace_, value);
 | 
						|
  if (!value.IsEmpty()) {
 | 
						|
    if (!ParseAttribute(value, mLeadingSpaceSign, mLeadingSpace,
 | 
						|
                        mLeadingSpacePseudoUnit)) {
 | 
						|
      ReportParseError(nsGkAtoms::lspace_->GetUTF16String(), value.get());
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  // voffset
 | 
						|
  mVerticalOffsetSign = NS_MATHML_SIGN_INVALID;
 | 
						|
  mContent->AsElement()->GetAttr(nsGkAtoms::voffset_, value);
 | 
						|
  if (!value.IsEmpty()) {
 | 
						|
    if (!ParseAttribute(value, mVerticalOffsetSign, mVerticalOffset,
 | 
						|
                        mVerticalOffsetPseudoUnit)) {
 | 
						|
      ReportParseError(nsGkAtoms::voffset_->GetUTF16String(), value.get());
 | 
						|
    }
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
// parse an input string in the following format (see bug 148326 for testcases):
 | 
						|
// [+|-] unsigned-number (% [pseudo-unit] | pseudo-unit | css-unit | namedspace)
 | 
						|
bool nsMathMLmpaddedFrame::ParseAttribute(nsString& aString, int32_t& aSign,
 | 
						|
                                          nsCSSValue& aCSSValue,
 | 
						|
                                          int32_t& aPseudoUnit) {
 | 
						|
  aCSSValue.Reset();
 | 
						|
  aSign = NS_MATHML_SIGN_INVALID;
 | 
						|
  aPseudoUnit = NS_MATHML_PSEUDO_UNIT_UNSPECIFIED;
 | 
						|
  aString.CompressWhitespace();  // aString is not a const in this code
 | 
						|
 | 
						|
  int32_t stringLength = aString.Length();
 | 
						|
  if (!stringLength) return false;
 | 
						|
 | 
						|
  nsAutoString number, unit;
 | 
						|
 | 
						|
  //////////////////////
 | 
						|
  // see if the sign is there
 | 
						|
 | 
						|
  int32_t i = 0;
 | 
						|
 | 
						|
  if (aString[0] == '+') {
 | 
						|
    aSign = NS_MATHML_SIGN_PLUS;
 | 
						|
    i++;
 | 
						|
  } else if (aString[0] == '-') {
 | 
						|
    aSign = NS_MATHML_SIGN_MINUS;
 | 
						|
    i++;
 | 
						|
  } else
 | 
						|
    aSign = NS_MATHML_SIGN_UNSPECIFIED;
 | 
						|
 | 
						|
  // get the number
 | 
						|
  bool gotDot = false, gotPercent = false;
 | 
						|
  for (; i < stringLength; i++) {
 | 
						|
    char16_t c = aString[i];
 | 
						|
    if (gotDot && c == '.') {
 | 
						|
      // error - two dots encountered
 | 
						|
      aSign = NS_MATHML_SIGN_INVALID;
 | 
						|
      return false;
 | 
						|
    }
 | 
						|
 | 
						|
    if (c == '.')
 | 
						|
      gotDot = true;
 | 
						|
    else if (!IsAsciiDigit(c)) {
 | 
						|
      break;
 | 
						|
    }
 | 
						|
    number.Append(c);
 | 
						|
  }
 | 
						|
 | 
						|
  // catch error if we didn't enter the loop above... we could simply initialize
 | 
						|
  // floatValue = 1, to cater for cases such as width="height", but that
 | 
						|
  // wouldn't be in line with the spec which requires an explicit number
 | 
						|
  if (number.IsEmpty()) {
 | 
						|
    aSign = NS_MATHML_SIGN_INVALID;
 | 
						|
    return false;
 | 
						|
  }
 | 
						|
 | 
						|
  nsresult errorCode;
 | 
						|
  float floatValue = number.ToFloat(&errorCode);
 | 
						|
  if (NS_FAILED(errorCode)) {
 | 
						|
    aSign = NS_MATHML_SIGN_INVALID;
 | 
						|
    return false;
 | 
						|
  }
 | 
						|
 | 
						|
  // see if this is a percentage-based value
 | 
						|
  if (i < stringLength && aString[i] == '%') {
 | 
						|
    i++;
 | 
						|
    gotPercent = true;
 | 
						|
  }
 | 
						|
 | 
						|
  // the remainder now should be a css-unit, or a pseudo-unit, or a named-space
 | 
						|
  aString.Right(unit, stringLength - i);
 | 
						|
 | 
						|
  if (unit.IsEmpty()) {
 | 
						|
    if (gotPercent) {
 | 
						|
      // case ["+"|"-"] unsigned-number "%"
 | 
						|
      aCSSValue.SetPercentValue(floatValue / 100.0f);
 | 
						|
      aPseudoUnit = NS_MATHML_PSEUDO_UNIT_ITSELF;
 | 
						|
      return true;
 | 
						|
    } else {
 | 
						|
      // case ["+"|"-"] unsigned-number
 | 
						|
      // XXXfredw: should we allow non-zero unitless values? See bug 757703.
 | 
						|
      if (!floatValue) {
 | 
						|
        aCSSValue.SetFloatValue(floatValue, eCSSUnit_Number);
 | 
						|
        aPseudoUnit = NS_MATHML_PSEUDO_UNIT_ITSELF;
 | 
						|
        return true;
 | 
						|
      }
 | 
						|
    }
 | 
						|
  } else if (unit.EqualsLiteral("width"))
 | 
						|
    aPseudoUnit = NS_MATHML_PSEUDO_UNIT_WIDTH;
 | 
						|
  else if (unit.EqualsLiteral("height"))
 | 
						|
    aPseudoUnit = NS_MATHML_PSEUDO_UNIT_HEIGHT;
 | 
						|
  else if (unit.EqualsLiteral("depth"))
 | 
						|
    aPseudoUnit = NS_MATHML_PSEUDO_UNIT_DEPTH;
 | 
						|
  else if (!gotPercent) {  // percentage can only apply to a pseudo-unit
 | 
						|
 | 
						|
    // see if the unit is a named-space
 | 
						|
    if (dom::MathMLElement::ParseNamedSpaceValue(
 | 
						|
            unit, aCSSValue, dom::MathMLElement::PARSE_ALLOW_NEGATIVE,
 | 
						|
            *mContent->OwnerDoc())) {
 | 
						|
      // re-scale properly, and we know that the unit of the named-space is 'em'
 | 
						|
      floatValue *= aCSSValue.GetFloatValue();
 | 
						|
      aCSSValue.SetFloatValue(floatValue, eCSSUnit_EM);
 | 
						|
      aPseudoUnit = NS_MATHML_PSEUDO_UNIT_NAMEDSPACE;
 | 
						|
      return true;
 | 
						|
    }
 | 
						|
 | 
						|
    // see if the input was just a CSS value
 | 
						|
    // We are not supposed to have a unitless, percent, negative or namedspace
 | 
						|
    // value here.
 | 
						|
    number.Append(unit);  // leave the sign out if it was there
 | 
						|
    if (dom::MathMLElement::ParseNumericValue(
 | 
						|
            number, aCSSValue, dom::MathMLElement::PARSE_SUPPRESS_WARNINGS,
 | 
						|
            nullptr))
 | 
						|
      return true;
 | 
						|
  }
 | 
						|
 | 
						|
  // if we enter here, we have a number that will act as a multiplier on a
 | 
						|
  // pseudo-unit
 | 
						|
  if (aPseudoUnit != NS_MATHML_PSEUDO_UNIT_UNSPECIFIED) {
 | 
						|
    if (gotPercent)
 | 
						|
      aCSSValue.SetPercentValue(floatValue / 100.0f);
 | 
						|
    else
 | 
						|
      aCSSValue.SetFloatValue(floatValue, eCSSUnit_Number);
 | 
						|
 | 
						|
    return true;
 | 
						|
  }
 | 
						|
 | 
						|
#ifdef DEBUG
 | 
						|
  printf("mpadded: attribute with bad numeric value: %s\n",
 | 
						|
         NS_LossyConvertUTF16toASCII(aString).get());
 | 
						|
#endif
 | 
						|
  // if we reach here, it means we encounter an unexpected input
 | 
						|
  aSign = NS_MATHML_SIGN_INVALID;
 | 
						|
  return false;
 | 
						|
}
 | 
						|
 | 
						|
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(), mComputedStyle, aCSSValue,
 | 
						|
                          aFontSizeInflation);
 | 
						|
 | 
						|
    if (NS_MATHML_SIGN_PLUS == aSign)
 | 
						|
      aValueToUpdate += amount;
 | 
						|
    else if (NS_MATHML_SIGN_MINUS == aSign)
 | 
						|
      aValueToUpdate -= amount;
 | 
						|
    else
 | 
						|
      aValueToUpdate = amount;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
void nsMathMLmpaddedFrame::Reflow(nsPresContext* aPresContext,
 | 
						|
                                  ReflowOutput& aDesiredSize,
 | 
						|
                                  const ReflowInput& aReflowInput,
 | 
						|
                                  nsReflowStatus& aStatus) {
 | 
						|
  MOZ_ASSERT(aStatus.IsEmpty(), "Caller should pass a fresh reflow status!");
 | 
						|
 | 
						|
  mPresentationData.flags &= ~NS_MATHML_ERROR;
 | 
						|
  ProcessAttributes();
 | 
						|
 | 
						|
  ///////////////
 | 
						|
  // Let the base class format our content like an inferred mrow
 | 
						|
  nsMathMLContainerFrame::Reflow(aPresContext, aDesiredSize, aReflowInput,
 | 
						|
                                 aStatus);
 | 
						|
  // NS_ASSERTION(aStatus.IsComplete(), "bad status");
 | 
						|
}
 | 
						|
 | 
						|
/* virtual */
 | 
						|
nsresult nsMathMLmpaddedFrame::Place(DrawTarget* aDrawTarget, bool aPlaceOrigin,
 | 
						|
                                     ReflowOutput& aDesiredSize) {
 | 
						|
  nsresult rv = nsMathMLContainerFrame::Place(aDrawTarget, false, aDesiredSize);
 | 
						|
  if (NS_MATHML_HAS_ERROR(mPresentationData.flags) || NS_FAILED(rv)) {
 | 
						|
    DidReflowChildren(PrincipalChildList().FirstChild());
 | 
						|
    return rv;
 | 
						|
  }
 | 
						|
 | 
						|
  nscoord height = aDesiredSize.BlockStartAscent();
 | 
						|
  nscoord depth = aDesiredSize.Height() - aDesiredSize.BlockStartAscent();
 | 
						|
  // The REC says:
 | 
						|
  //
 | 
						|
  // "The lspace attribute ('leading' space) specifies the horizontal location
 | 
						|
  // of the positioning point of the child content with respect to the
 | 
						|
  // positioning point of the mpadded element. By default they coincide, and
 | 
						|
  // therefore absolute values for lspace have the same effect as relative
 | 
						|
  // values."
 | 
						|
  //
 | 
						|
  // "MathML renderers should ensure that, except for the effects of the
 | 
						|
  // attributes, the relative spacing between the contents of the mpadded
 | 
						|
  // element and surrounding MathML elements would not be modified by replacing
 | 
						|
  // an mpadded element with an mrow element with the same content, even if
 | 
						|
  // linebreaking occurs within the mpadded element."
 | 
						|
  //
 | 
						|
  // (http://www.w3.org/TR/MathML/chapter3.html#presm.mpadded)
 | 
						|
  //
 | 
						|
  // "In those discussions, the terms leading and trailing are used to specify
 | 
						|
  // a side of an object when which side to use depends on the directionality;
 | 
						|
  // ie. leading means left in LTR but right in RTL."
 | 
						|
  // (http://www.w3.org/TR/MathML/chapter3.html#presm.bidi.math)
 | 
						|
  nscoord lspace = 0;
 | 
						|
  // In MathML3, "width" will be the bounding box width and "advancewidth" will
 | 
						|
  // refer "to the horizontal distance between the positioning point of the
 | 
						|
  // mpadded and the positioning point for the following content".  MathML2
 | 
						|
  // doesn't make the distinction.
 | 
						|
  nscoord width = aDesiredSize.Width();
 | 
						|
  nscoord voffset = 0;
 | 
						|
 | 
						|
  int32_t pseudoUnit;
 | 
						|
  nscoord initialWidth = width;
 | 
						|
  float fontSizeInflation = nsLayoutUtils::FontSizeInflationFor(this);
 | 
						|
 | 
						|
  // update width
 | 
						|
  pseudoUnit = (mWidthPseudoUnit == NS_MATHML_PSEUDO_UNIT_ITSELF)
 | 
						|
                   ? NS_MATHML_PSEUDO_UNIT_WIDTH
 | 
						|
                   : mWidthPseudoUnit;
 | 
						|
  UpdateValue(mWidthSign, pseudoUnit, mWidth, aDesiredSize, width,
 | 
						|
              fontSizeInflation);
 | 
						|
  width = std::max(0, width);
 | 
						|
 | 
						|
  // update "height" (this is the ascent in the terminology of the REC)
 | 
						|
  pseudoUnit = (mHeightPseudoUnit == NS_MATHML_PSEUDO_UNIT_ITSELF)
 | 
						|
                   ? NS_MATHML_PSEUDO_UNIT_HEIGHT
 | 
						|
                   : mHeightPseudoUnit;
 | 
						|
  UpdateValue(mHeightSign, pseudoUnit, mHeight, aDesiredSize, height,
 | 
						|
              fontSizeInflation);
 | 
						|
  height = std::max(0, height);
 | 
						|
 | 
						|
  // update "depth" (this is the descent in the terminology of the REC)
 | 
						|
  pseudoUnit = (mDepthPseudoUnit == NS_MATHML_PSEUDO_UNIT_ITSELF)
 | 
						|
                   ? NS_MATHML_PSEUDO_UNIT_DEPTH
 | 
						|
                   : mDepthPseudoUnit;
 | 
						|
  UpdateValue(mDepthSign, pseudoUnit, mDepth, aDesiredSize, depth,
 | 
						|
              fontSizeInflation);
 | 
						|
  depth = std::max(0, depth);
 | 
						|
 | 
						|
  // update lspace
 | 
						|
  if (mLeadingSpacePseudoUnit != NS_MATHML_PSEUDO_UNIT_ITSELF) {
 | 
						|
    pseudoUnit = mLeadingSpacePseudoUnit;
 | 
						|
    UpdateValue(mLeadingSpaceSign, pseudoUnit, mLeadingSpace, aDesiredSize,
 | 
						|
                lspace, fontSizeInflation);
 | 
						|
  }
 | 
						|
 | 
						|
  // update voffset
 | 
						|
  if (mVerticalOffsetPseudoUnit != NS_MATHML_PSEUDO_UNIT_ITSELF) {
 | 
						|
    pseudoUnit = mVerticalOffsetPseudoUnit;
 | 
						|
    UpdateValue(mVerticalOffsetSign, pseudoUnit, mVerticalOffset, aDesiredSize,
 | 
						|
                voffset, fontSizeInflation);
 | 
						|
  }
 | 
						|
  // do the padding now that we have everything
 | 
						|
  // The idea here is to maintain the invariant that <mpadded>...</mpadded>
 | 
						|
  // (i.e., with no attributes) looks the same as <mrow>...</mrow>. But when
 | 
						|
  // there are attributes, tweak our metrics and move children to achieve the
 | 
						|
  // desired visual effects.
 | 
						|
 | 
						|
  const bool isRTL = StyleVisibility()->mDirection == StyleDirection::Rtl;
 | 
						|
  if ((isRTL ? mWidthSign : mLeadingSpaceSign) != NS_MATHML_SIGN_INVALID) {
 | 
						|
    // there was padding on the left. dismiss the left italic correction now
 | 
						|
    // (so that our parent won't correct us)
 | 
						|
    mBoundingMetrics.leftBearing = 0;
 | 
						|
  }
 | 
						|
 | 
						|
  if ((isRTL ? mLeadingSpaceSign : mWidthSign) != NS_MATHML_SIGN_INVALID) {
 | 
						|
    // there was padding on the right. dismiss the right italic correction now
 | 
						|
    // (so that our parent won't correct us)
 | 
						|
    mBoundingMetrics.width = width;
 | 
						|
    mBoundingMetrics.rightBearing = mBoundingMetrics.width;
 | 
						|
  }
 | 
						|
 | 
						|
  nscoord dx = (isRTL ? width - initialWidth - lspace : lspace);
 | 
						|
 | 
						|
  aDesiredSize.SetBlockStartAscent(height);
 | 
						|
  aDesiredSize.Width() = mBoundingMetrics.width;
 | 
						|
  aDesiredSize.Height() = depth + aDesiredSize.BlockStartAscent();
 | 
						|
  mBoundingMetrics.ascent = height;
 | 
						|
  mBoundingMetrics.descent = depth;
 | 
						|
  aDesiredSize.mBoundingMetrics = mBoundingMetrics;
 | 
						|
 | 
						|
  mReference.x = 0;
 | 
						|
  mReference.y = aDesiredSize.BlockStartAscent();
 | 
						|
 | 
						|
  if (aPlaceOrigin) {
 | 
						|
    // Finish reflowing child frames, positioning their origins.
 | 
						|
    PositionRowChildFrames(dx, aDesiredSize.BlockStartAscent() - voffset);
 | 
						|
  }
 | 
						|
 | 
						|
  return NS_OK;
 | 
						|
}
 | 
						|
 | 
						|
/* virtual */
 | 
						|
nsresult nsMathMLmpaddedFrame::MeasureForWidth(DrawTarget* aDrawTarget,
 | 
						|
                                               ReflowOutput& aDesiredSize) {
 | 
						|
  ProcessAttributes();
 | 
						|
  return Place(aDrawTarget, false, aDesiredSize);
 | 
						|
}
 |