Make lspace/rspace in mo behave as leading/trailing spaces (bug 534963). r=karlt
authorFrédéric Wang <fred.wang@free.fr>
Wed, 21 Dec 2011 17:21:59 -0500
changeset 83220 4a7965d14389aa0700752708cfdb581a8095884f
parent 83219 05fee5eb0473f5cb406997503eb09dacd87bfd1b
child 83221 80ecebafe90b32e2f433730988a5665c2475efd2
push id21742
push userbmo@edmorley.co.uk
push dateThu, 22 Dec 2011 11:29:57 +0000
treeherdermozilla-central@c5b90ea7e475 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskarlt
bugs534963
milestone12.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Make lspace/rspace in mo behave as leading/trailing spaces (bug 534963). r=karlt
layout/mathml/nsIMathMLFrame.h
layout/mathml/nsMathMLContainerFrame.cpp
layout/mathml/nsMathMLFrame.cpp
layout/mathml/nsMathMLOperators.cpp
layout/mathml/nsMathMLOperators.h
layout/mathml/nsMathMLmfracFrame.cpp
layout/mathml/nsMathMLmoFrame.cpp
--- a/layout/mathml/nsIMathMLFrame.h
+++ b/layout/mathml/nsIMathMLFrame.h
@@ -250,25 +250,25 @@ struct nsEmbellishData {
 
   // stretchy direction that the nsMathMLChar owned by the core <mo> supports
   nsStretchDirection direction;
 
   // spacing that may come from <mo> depending on its 'form'. Since
   // the 'form' may also depend on the position of the outermost
   // embellished ancestor, the set up of these values may require
   // looking up the position of our ancestors.
-  nscoord leftSpace;
-  nscoord rightSpace;
+  nscoord leadingSpace;
+  nscoord trailingSpace;
 
   nsEmbellishData() {
     flags = 0;
     coreFrame = nsnull;
     direction = NS_STRETCH_DIRECTION_UNSUPPORTED;
-    leftSpace = 0;
-    rightSpace = 0;
+    leadingSpace = 0;
+    trailingSpace = 0;
   }
 };
 
 // struct used by a container frame to modulate its presentation.
 // By convention, the data that we keep in this struct can change depending
 // on any of our ancestors and/or descendants. If a data can be resolved
 // solely from the embellished hierarchy, and it remains immutable once
 // resolved, we put it in |nsEmbellishData|. If it can be affected by other
--- a/layout/mathml/nsMathMLContainerFrame.cpp
+++ b/layout/mathml/nsMathMLContainerFrame.cpp
@@ -440,21 +440,23 @@ nsMathMLContainerFrame::Stretch(nsRender
         // (need to test coreFrame since <mfrac> resets other things)
         if (parentData.coreFrame != mEmbellishData.coreFrame) {
           // (we fetch values from the core since they may use units that depend
           // on style data, and style changes could have occurred in the core since
           // our last visit there)
           nsEmbellishData coreData;
           GetEmbellishDataFrom(mEmbellishData.coreFrame, coreData);
 
-          mBoundingMetrics.width += coreData.leftSpace + coreData.rightSpace;
+          mBoundingMetrics.width +=
+            coreData.leadingSpace + coreData.trailingSpace;
           aDesiredStretchSize.width = mBoundingMetrics.width;
           aDesiredStretchSize.mBoundingMetrics.width = mBoundingMetrics.width;
 
-          nscoord dx = coreData.leftSpace;
+          nscoord dx = (NS_MATHML_IS_RTL(mPresentationData.flags) ?
+                        coreData.trailingSpace : coreData.leadingSpace);
           if (dx != 0) {
             mBoundingMetrics.leftBearing += dx;
             mBoundingMetrics.rightBearing += dx;
             aDesiredStretchSize.mBoundingMetrics.leftBearing += dx;
             aDesiredStretchSize.mBoundingMetrics.rightBearing += dx;
 
             nsIFrame* childFrame = mFrames.FirstChild();
             while (childFrame) {
@@ -1523,18 +1525,18 @@ nsMathMLContainerFrame::TransmitAutomati
   }
 
   if (childFrame || !embellishedOpFound) {
     // The element is not embellished operator
     mPresentationData.baseFrame = nsnull;
     mEmbellishData.flags = 0;
     mEmbellishData.coreFrame = nsnull;
     mEmbellishData.direction = NS_STRETCH_DIRECTION_UNSUPPORTED;
-    mEmbellishData.leftSpace = 0;
-    mEmbellishData.rightSpace = 0;
+    mEmbellishData.leadingSpace = 0;
+    mEmbellishData.trailingSpace = 0;
   }
 
   if (childFrame || embellishedOpFound) {
     // The element is not space-like
     mPresentationData.flags &= ~NS_MATHML_SPACE_LIKE;
   }
 
   return NS_OK;
--- a/layout/mathml/nsMathMLFrame.cpp
+++ b/layout/mathml/nsMathMLFrame.cpp
@@ -121,18 +121,18 @@ nsMathMLFrame::FindAttrDirectionality(ns
 }
 
 NS_IMETHODIMP
 nsMathMLFrame::InheritAutomaticData(nsIFrame* aParent) 
 {
   mEmbellishData.flags = 0;
   mEmbellishData.coreFrame = nsnull;
   mEmbellishData.direction = NS_STRETCH_DIRECTION_UNSUPPORTED;
-  mEmbellishData.leftSpace = 0;
-  mEmbellishData.rightSpace = 0;
+  mEmbellishData.leadingSpace = 0;
+  mEmbellishData.trailingSpace = 0;
 
   mPresentationData.flags = 0;
   mPresentationData.baseFrame = nsnull;
   mPresentationData.mstyle = nsnull;
 
   // by default, just inherit the display of our parent
   nsPresentationData parentData;
   GetPresentationDataFrom(aParent, parentData);
@@ -206,18 +206,18 @@ nsMathMLFrame::ResolveMathMLCharStyle(ns
 /* static */ void
 nsMathMLFrame::GetEmbellishDataFrom(nsIFrame*        aFrame,
                                     nsEmbellishData& aEmbellishData)
 {
   // initialize OUT params
   aEmbellishData.flags = 0;
   aEmbellishData.coreFrame = nsnull;
   aEmbellishData.direction = NS_STRETCH_DIRECTION_UNSUPPORTED;
-  aEmbellishData.leftSpace = 0;
-  aEmbellishData.rightSpace = 0;
+  aEmbellishData.leadingSpace = 0;
+  aEmbellishData.trailingSpace = 0;
 
   if (aFrame && aFrame->IsFrameOfType(nsIFrame::eMathML)) {
     nsIMathMLFrame* mathMLFrame = do_QueryFrame(aFrame);
     if (mathMLFrame) {
       mathMLFrame->GetEmbellishData(aEmbellishData);
     }
   }
 }
--- a/layout/mathml/nsMathMLOperators.cpp
+++ b/layout/mathml/nsMathMLOperators.cpp
@@ -49,26 +49,26 @@
 #include "nsCRT.h"
 
 #include "nsMathMLOperators.h"
 
 // operator dictionary entry
 struct OperatorData {
   OperatorData(void)
     : mFlags(0),
-      mLeftSpace(0.0f),
-      mRightSpace(0.0f)
+      mLeadingSpace(0.0f),
+      mTrailingSpace(0.0f)
   {
   }
 
   // member data
   nsString        mStr;
   nsOperatorFlags mFlags;
-  float           mLeftSpace;   // unit is em
-  float           mRightSpace;  // unit is em
+  float           mLeadingSpace;   // unit is em
+  float           mTrailingSpace;  // unit is em
 };
 
 static PRInt32         gTableRefCount = 0;
 static PRUint32        gOperatorCount = 0;
 static OperatorData*   gOperatorArray = nsnull;
 static nsHashtable*    gOperatorTable = nsnull;
 static bool            gInitialized   = false;
 static nsTArray<nsString>*      gInvariantCharArray    = nsnull;
@@ -134,32 +134,32 @@ SetProperty(OperatorData* aOperatorData,
 
   if (aName.EqualsLiteral("direction")) {
     if (aValue.EqualsLiteral("vertical"))
       aOperatorData->mFlags |= NS_MATHML_OPERATOR_DIRECTION_VERTICAL;
     else if (aValue.EqualsLiteral("horizontal"))
       aOperatorData->mFlags |= NS_MATHML_OPERATOR_DIRECTION_HORIZONTAL;
     else return; // invalid value
   } else {
-    bool isLeftSpace;
+    bool isLeadingSpace;
     if (aName.EqualsLiteral("lspace"))
-      isLeftSpace = true;
+      isLeadingSpace = true;
     else if (aName.EqualsLiteral("rspace"))
-      isLeftSpace = false;
+      isLeadingSpace = false;
     else return;  // input is not applicable
 
     // aValue is assumed to be a digit from 0 to 7
     PRInt32 error = 0;
     float space = aValue.ToFloat(&error) / 18.0;
     if (error) return;
 
-    if (isLeftSpace)
-      aOperatorData->mLeftSpace = space;
+    if (isLeadingSpace)
+      aOperatorData->mLeadingSpace = space;
     else
-      aOperatorData->mRightSpace = space;
+      aOperatorData->mTrailingSpace = space;
   }
 }
 
 static bool
 SetOperator(OperatorData*   aOperatorData,
             nsOperatorFlags aForm,
             const nsCString& aOperator,
             nsString&        aAttributes)
@@ -404,24 +404,24 @@ GetOperatorData(const nsString& aOperato
   nsStringKey hkey(key);
   return (OperatorData*)gOperatorTable->Get(&hkey);
 }
 
 bool
 nsMathMLOperators::LookupOperator(const nsString&       aOperator,
                                   const nsOperatorFlags aForm,
                                   nsOperatorFlags*      aFlags,
-                                  float*                aLeftSpace,
-                                  float*                aRightSpace)
+                                  float*                aLeadingSpace,
+                                  float*                aTrailingSpace)
 {
   if (!gInitialized) {
     InitGlobals();
   }
   if (gOperatorTable) {
-    NS_ASSERTION(aFlags && aLeftSpace && aRightSpace, "bad usage");
+    NS_ASSERTION(aFlags && aLeadingSpace && aTrailingSpace, "bad usage");
     NS_ASSERTION(aForm > 0 && aForm < 4, "*** invalid call ***");
 
     // The MathML REC says:
     // If the operator does not occur in the dictionary with the specified form,
     // the renderer should use one of the forms which is available there, in the
     // order of preference: infix, postfix, prefix.
 
     OperatorData* found;
@@ -436,67 +436,67 @@ nsMathMLOperators::LookupOperator(const 
           if (form != NS_MATHML_OPERATOR_FORM_PREFIX) {
             found = GetOperatorData(aOperator, NS_MATHML_OPERATOR_FORM_PREFIX);
           }
         }
       }
     }
     if (found) {
       NS_ASSERTION(found->mStr.Equals(aOperator), "bad setup");
-      *aLeftSpace = found->mLeftSpace;
-      *aRightSpace = found->mRightSpace;
+      *aLeadingSpace = found->mLeadingSpace;
+      *aTrailingSpace = found->mTrailingSpace;
       *aFlags &= ~NS_MATHML_OPERATOR_FORM; // clear the form bits
       *aFlags |= found->mFlags; // just add bits without overwriting
       return true;
     }
   }
   return false;
 }
 
 void
 nsMathMLOperators::LookupOperators(const nsString&       aOperator,
                                    nsOperatorFlags*      aFlags,
-                                   float*                aLeftSpace,
-                                   float*                aRightSpace)
+                                   float*                aLeadingSpace,
+                                   float*                aTrailingSpace)
 {
   if (!gInitialized) {
     InitGlobals();
   }
 
   aFlags[NS_MATHML_OPERATOR_FORM_INFIX] = 0;
-  aLeftSpace[NS_MATHML_OPERATOR_FORM_INFIX] = 0.0f;
-  aRightSpace[NS_MATHML_OPERATOR_FORM_INFIX] = 0.0f;
+  aLeadingSpace[NS_MATHML_OPERATOR_FORM_INFIX] = 0.0f;
+  aTrailingSpace[NS_MATHML_OPERATOR_FORM_INFIX] = 0.0f;
 
   aFlags[NS_MATHML_OPERATOR_FORM_POSTFIX] = 0;
-  aLeftSpace[NS_MATHML_OPERATOR_FORM_POSTFIX] = 0.0f;
-  aRightSpace[NS_MATHML_OPERATOR_FORM_POSTFIX] = 0.0f;
+  aLeadingSpace[NS_MATHML_OPERATOR_FORM_POSTFIX] = 0.0f;
+  aTrailingSpace[NS_MATHML_OPERATOR_FORM_POSTFIX] = 0.0f;
 
   aFlags[NS_MATHML_OPERATOR_FORM_PREFIX] = 0;
-  aLeftSpace[NS_MATHML_OPERATOR_FORM_PREFIX] = 0.0f;
-  aRightSpace[NS_MATHML_OPERATOR_FORM_PREFIX] = 0.0f;
+  aLeadingSpace[NS_MATHML_OPERATOR_FORM_PREFIX] = 0.0f;
+  aTrailingSpace[NS_MATHML_OPERATOR_FORM_PREFIX] = 0.0f;
 
   if (gOperatorTable) {
     OperatorData* found;
     found = GetOperatorData(aOperator, NS_MATHML_OPERATOR_FORM_INFIX);
     if (found) {
       aFlags[NS_MATHML_OPERATOR_FORM_INFIX] = found->mFlags;
-      aLeftSpace[NS_MATHML_OPERATOR_FORM_INFIX] = found->mLeftSpace;
-      aRightSpace[NS_MATHML_OPERATOR_FORM_INFIX] = found->mRightSpace;
+      aLeadingSpace[NS_MATHML_OPERATOR_FORM_INFIX] = found->mLeadingSpace;
+      aTrailingSpace[NS_MATHML_OPERATOR_FORM_INFIX] = found->mTrailingSpace;
     }
     found = GetOperatorData(aOperator, NS_MATHML_OPERATOR_FORM_POSTFIX);
     if (found) {
       aFlags[NS_MATHML_OPERATOR_FORM_POSTFIX] = found->mFlags;
-      aLeftSpace[NS_MATHML_OPERATOR_FORM_POSTFIX] = found->mLeftSpace;
-      aRightSpace[NS_MATHML_OPERATOR_FORM_POSTFIX] = found->mRightSpace;
+      aLeadingSpace[NS_MATHML_OPERATOR_FORM_POSTFIX] = found->mLeadingSpace;
+      aTrailingSpace[NS_MATHML_OPERATOR_FORM_POSTFIX] = found->mTrailingSpace;
     }
     found = GetOperatorData(aOperator, NS_MATHML_OPERATOR_FORM_PREFIX);
     if (found) {
       aFlags[NS_MATHML_OPERATOR_FORM_PREFIX] = found->mFlags;
-      aLeftSpace[NS_MATHML_OPERATOR_FORM_PREFIX] = found->mLeftSpace;
-      aRightSpace[NS_MATHML_OPERATOR_FORM_PREFIX] = found->mRightSpace;
+      aLeadingSpace[NS_MATHML_OPERATOR_FORM_PREFIX] = found->mLeadingSpace;
+      aTrailingSpace[NS_MATHML_OPERATOR_FORM_PREFIX] = found->mTrailingSpace;
     }
   }
 }
 
 bool
 nsMathMLOperators::IsMutableOperator(const nsString& aOperator)
 {
   if (!gInitialized) {
--- a/layout/mathml/nsMathMLOperators.h
+++ b/layout/mathml/nsMathMLOperators.h
@@ -80,18 +80,18 @@ enum {
   NS_MATHML_OPERATOR_SEPARATOR          = 1<<8,
   NS_MATHML_OPERATOR_MOVABLELIMITS      = 1<<9,
   NS_MATHML_OPERATOR_SYMMETRIC          = 1<<10,
   NS_MATHML_OPERATOR_INTEGRAL           = 1<<11,
 
   // Additional bits not stored in the dictionary
   NS_MATHML_OPERATOR_MINSIZE_ABSOLUTE   = 1<<12,
   NS_MATHML_OPERATOR_MAXSIZE_ABSOLUTE   = 1<<13,
-  NS_MATHML_OPERATOR_LEFTSPACE_ATTR     = 1<<14,
-  NS_MATHML_OPERATOR_RIGHTSPACE_ATTR    = 1<<15
+  NS_MATHML_OPERATOR_LSPACE_ATTR     = 1<<14,
+  NS_MATHML_OPERATOR_RSPACE_ATTR    = 1<<15
 };
 
 #define NS_MATHML_OPERATOR_SIZE_INFINITY NS_IEEEPositiveInfinity()
 
 // Style invariant characters (chars have their own intrinsic predefined style)
 enum eMATHVARIANT {
   eMATHVARIANT_NONE = -1,
   eMATHVARIANT_normal = 0,
@@ -124,30 +124,31 @@ public:
   // If the operator is not found under the supplied form but is found under a 
   // different form, the method returns true as well. The caller can test the
   // output parameter aFlags to know exactly under which form the operator was
   // found in the Operator Dictionary.
   static bool
   LookupOperator(const nsString&       aOperator,
                  const nsOperatorFlags aForm,
                  nsOperatorFlags*      aFlags,
-                 float*                aLeftSpace,
-                 float*                aRightSpace);
+                 float*                aLeadingSpace,
+                 float*                aTrailingSpace);
 
    // LookupOperators:
    // Helper to return all the forms under which an operator is listed in the
    // Operator Dictionary. The caller must pass arrays of size 4, and use 
-   // aFlags[NS_MATHML_OPERATOR_FORM_{INFIX|POSTFIX|PREFIX}], aLeftSpace[], etc,
-   // to access the attributes of the operator under a particular form. If the
-   // operator wasn't found under a form, its entry aFlags[form] is set to zero.
+   // aFlags[NS_MATHML_OPERATOR_FORM_{INFIX|POSTFIX|PREFIX}],
+   // aLeadingSpace[], etc, to access the attributes of the operator under a
+   // particular form. If the operator wasn't found under a form, its entry
+   // aFlags[form] is set to zero.
    static void
    LookupOperators(const nsString&       aOperator,
                    nsOperatorFlags*      aFlags,
-                   float*                aLeftSpace,
-                   float*                aRightSpace);
+                   float*                aLeadingSpace,
+                   float*                aTrailingSpace);
 
   // IsMutableOperator:
   // Return true if the operator exists and is stretchy or largeop
   static bool
   IsMutableOperator(const nsString& aOperator);
 
   // Helper function used by the nsMathMLChar class.
   static nsStretchDirection GetStretchyDirection(const nsString& aOperator);
@@ -230,15 +231,15 @@ public:
   (NS_MATHML_OPERATOR_INTEGRAL == ((_flags) & NS_MATHML_OPERATOR_INTEGRAL))
 
 #define NS_MATHML_OPERATOR_MINSIZE_IS_ABSOLUTE(_flags) \
   (NS_MATHML_OPERATOR_MINSIZE_ABSOLUTE == ((_flags) & NS_MATHML_OPERATOR_MINSIZE_ABSOLUTE))
 
 #define NS_MATHML_OPERATOR_MAXSIZE_IS_ABSOLUTE(_flags) \
   (NS_MATHML_OPERATOR_MAXSIZE_ABSOLUTE == ((_flags) & NS_MATHML_OPERATOR_MAXSIZE_ABSOLUTE))
 
-#define NS_MATHML_OPERATOR_HAS_LEFTSPACE_ATTR(_flags) \
-  (NS_MATHML_OPERATOR_LEFTSPACE_ATTR == ((_flags) & NS_MATHML_OPERATOR_LEFTSPACE_ATTR))
+#define NS_MATHML_OPERATOR_HAS_LSPACE_ATTR(_flags) \
+  (NS_MATHML_OPERATOR_LSPACE_ATTR == ((_flags) & NS_MATHML_OPERATOR_LSPACE_ATTR))
 
-#define NS_MATHML_OPERATOR_HAS_RIGHTSPACE_ATTR(_flags) \
-  (NS_MATHML_OPERATOR_RIGHTSPACE_ATTR == ((_flags) & NS_MATHML_OPERATOR_RIGHTSPACE_ATTR))
+#define NS_MATHML_OPERATOR_HAS_RSPACE_ATTR(_flags) \
+  (NS_MATHML_OPERATOR_RSPACE_ATTR == ((_flags) & NS_MATHML_OPERATOR_RSPACE_ATTR))
 
 #endif /* nsMathMLOperators_h___ */
--- a/layout/mathml/nsMathMLmfracFrame.cpp
+++ b/layout/mathml/nsMathMLmfracFrame.cpp
@@ -267,18 +267,22 @@ nsMathMLmfracFrame::PlaceInternal(nsRend
   if (!mIsBevelled) {
     mLineRect.height = mLineThickness;
     
     // by default, leave at least one-pixel padding at either end, or use
     // lspace & rspace that may come from <mo> if we are an embellished
     // container (we fetch values from the core since they may use units that
     // depend on style data, and style changes could have occurred in the
     // core since our last visit there)
-    nscoord leftSpace = NS_MAX(onePixel, coreData.leftSpace);
-    nscoord rightSpace = NS_MAX(onePixel, coreData.rightSpace);
+    nscoord leftSpace = NS_MAX(onePixel,
+                               NS_MATHML_IS_RTL(mPresentationData.flags) ?
+                               coreData.trailingSpace : coreData.leadingSpace);
+    nscoord rightSpace = NS_MAX(onePixel,
+                                NS_MATHML_IS_RTL(mPresentationData.flags) ?
+                                coreData.leadingSpace : coreData.trailingSpace);
 
     //////////////////
     // Get shifts
     nscoord numShift = 0;
     nscoord denShift = 0;
 
     // Rule 15b, App. G, TeXbook
     nscoord numShift1, numShift2, numShift3;
@@ -417,18 +421,18 @@ nsMathMLmfracFrame::PlaceInternal(nsRend
     nscoord em = fm->EmHeight();
     nscoord slashMaxWidthConstant = 2 * em;
 
     // For large line thicknesses the minimum slash height is limited to the
     // largest expected height of a fraction
     nscoord slashMinHeight = slashRatio *
       NS_MIN(2 * mLineThickness, slashMaxWidthConstant);
 
-    nscoord leftSpace = NS_MAX(padding, coreData.leftSpace);
-    nscoord rightSpace = NS_MAX(padding, coreData.rightSpace);
+    nscoord leadingSpace = NS_MAX(padding, coreData.leadingSpace);
+    nscoord trailingSpace = NS_MAX(padding, coreData.trailingSpace);
     nscoord delta;
     
     //           ___________
     //          |           |    /
     //         {|-NUMERATOR-|   /
     //         {|___________|  S
     //         {               L
     // numShift{               A
@@ -479,51 +483,56 @@ nsMathMLmfracFrame::PlaceInternal(nsRend
     } else {
       mLineRect.width = mLineThickness +
         NS_MIN(slashMaxWidthConstant,
                (mBoundingMetrics.ascent + mBoundingMetrics.descent) /
                slashRatio);
     }
 
     // Set horizontal bounding metrics
-    mBoundingMetrics.leftBearing = leftSpace + bmNum.leftBearing;
-    mBoundingMetrics.rightBearing =
-      leftSpace + bmNum.width + mLineRect.width + bmDen.rightBearing;
+    if (NS_MATHML_IS_RTL(mPresentationData.flags)) {
+      mBoundingMetrics.leftBearing = trailingSpace + bmDen.leftBearing;
+      mBoundingMetrics.rightBearing = trailingSpace + bmDen.width + mLineRect.width + bmNum.rightBearing;
+    } else {
+      mBoundingMetrics.leftBearing = leadingSpace + bmNum.leftBearing;
+      mBoundingMetrics.rightBearing = leadingSpace + bmNum.width + mLineRect.width + bmDen.rightBearing;
+    }
     mBoundingMetrics.width =
-      leftSpace + bmNum.width + mLineRect.width + bmDen.width + rightSpace;
+      leadingSpace + bmNum.width + mLineRect.width + bmDen.width +
+      trailingSpace;
 
     // Set aDesiredSize
     aDesiredSize.ascent = mBoundingMetrics.ascent + padding;
     aDesiredSize.height =
       mBoundingMetrics.ascent + mBoundingMetrics.descent + 2 * padding;
     aDesiredSize.width = mBoundingMetrics.width;
     aDesiredSize.mBoundingMetrics = mBoundingMetrics;
 
     mReference.x = 0;
     mReference.y = aDesiredSize.ascent;
     
     if (aPlaceOrigin) {
       nscoord dx, dy;
 
       // place numerator
       dx = MirrorIfRTL(aDesiredSize.width, sizeNum.width,
-                       leftSpace);
+                       leadingSpace);
       dy = aDesiredSize.ascent - numShift - sizeNum.ascent;
       FinishReflowChild(frameNum, presContext, nsnull, sizeNum, dx, dy, 0);
 
       // place the fraction bar
       dx = MirrorIfRTL(aDesiredSize.width, mLineRect.width,
-                       leftSpace + bmNum.width);
+                       leadingSpace + bmNum.width);
       dy = aDesiredSize.ascent - mBoundingMetrics.ascent;
       mLineRect.SetRect(dx, dy,
                         mLineRect.width, aDesiredSize.height - 2 * padding);
 
       // place denominator
       dx = MirrorIfRTL(aDesiredSize.width, sizeDen.width,
-                       leftSpace + bmNum.width + mLineRect.width);
+                       leadingSpace + bmNum.width + mLineRect.width);
       dy = aDesiredSize.ascent + denShift - sizeDen.ascent;
       FinishReflowChild(frameDen, presContext, nsnull, sizeDen, dx, dy, 0);
     }
 
   }
 
   return NS_OK;
 }
--- a/layout/mathml/nsMathMLmoFrame.cpp
+++ b/layout/mathml/nsMathMLmoFrame.cpp
@@ -261,18 +261,18 @@ nsMathMLmoFrame::ProcessOperatorData()
   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 = nsnull;
-    mEmbellishData.leftSpace = 0;
-    mEmbellishData.rightSpace = 0;
+    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;
     }
 
@@ -385,86 +385,86 @@ nsMathMLmoFrame::ProcessOperatorData()
     if (found && (lspace || rspace)) {
       // cache the default values of lspace & rspace that we get from the dictionary.
       // 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.leftSpace = NSToCoordRound(lspace * em);
-      mEmbellishData.rightSpace = NSToCoordRound(rspace * 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 (GetStyleFont()->mScriptLevel > 0) {
         if (NS_MATHML_OPERATOR_EMBELLISH_IS_ISOLATED(mFlags)) {
           // could be an isolated accent or script, e.g., x^{+}, just zero out
-          mEmbellishData.leftSpace = 0;
-          mEmbellishData.rightSpace  = 0;
+          mEmbellishData.leadingSpace = 0;
+          mEmbellishData.trailingSpace  = 0;
         }
         else if (!NS_MATHML_OPERATOR_HAS_EMBELLISH_ANCESTOR(mFlags)) {
-          mEmbellishData.leftSpace /= 2;
-          mEmbellishData.rightSpace  /= 2;
+          mEmbellishData.leadingSpace /= 2;
+          mEmbellishData.trailingSpace  /= 2;
         }
       }
     }
   }
 
   // If we are an accent without explicit lspace="." or rspace=".",
-  // we will ignore our default left/right space
+  // we will ignore our default leading/trailing space
 
   // lspace = number h-unit | namedspace
-  nscoord leftSpace = mEmbellishData.leftSpace;
+  nscoord leadingSpace = mEmbellishData.leadingSpace;
   GetAttribute(mContent, mPresentationData.mstyle, nsGkAtoms::lspace_,
                value);
   if (!value.IsEmpty()) {
     nsCSSValue cssValue;
     if (ParseNumericValue(value, cssValue) ||
         ParseNamedSpaceValue(mPresentationData.mstyle, value, cssValue))
     {
       if ((eCSSUnit_Number == cssValue.GetUnit()) && !cssValue.GetFloatValue())
-        leftSpace = 0;
+        leadingSpace = 0;
       else if (cssValue.IsLengthUnit())
-        leftSpace = CalcLength(presContext, mStyleContext, cssValue);
-      mFlags |= NS_MATHML_OPERATOR_LEFTSPACE_ATTR;
+        leadingSpace = CalcLength(presContext, mStyleContext, cssValue);
+      mFlags |= NS_MATHML_OPERATOR_LSPACE_ATTR;
     }
   }
 
   // rspace = number h-unit | namedspace
-  nscoord rightSpace = mEmbellishData.rightSpace;
+  nscoord trailingSpace = mEmbellishData.trailingSpace;
   GetAttribute(mContent, mPresentationData.mstyle, nsGkAtoms::rspace_,
                value);
   if (!value.IsEmpty()) {
     nsCSSValue cssValue;
     if (ParseNumericValue(value, cssValue) ||
         ParseNamedSpaceValue(mPresentationData.mstyle, value, cssValue))
     {
       if ((eCSSUnit_Number == cssValue.GetUnit()) && !cssValue.GetFloatValue())
-        rightSpace = 0;
+        trailingSpace = 0;
       else if (cssValue.IsLengthUnit())
-        rightSpace = CalcLength(presContext, mStyleContext, cssValue);
-      mFlags |= NS_MATHML_OPERATOR_RIGHTSPACE_ATTR;
+        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 (leftSpace || rightSpace) {
+  if (leadingSpace || trailingSpace) {
     nscoord onePixel = nsPresContext::CSSPixelsToAppUnits(1);
-    if (leftSpace && leftSpace < onePixel)
-      leftSpace = onePixel;
-    if (rightSpace && rightSpace < onePixel)
-      rightSpace = onePixel;
+    if (leadingSpace && leadingSpace < onePixel)
+      leadingSpace = onePixel;
+    if (trailingSpace && trailingSpace < onePixel)
+      trailingSpace = onePixel;
   }
 
   // the values that we get from our attributes override the dictionary
-  mEmbellishData.leftSpace = leftSpace;
-  mEmbellishData.rightSpace = rightSpace;
+  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,
@@ -866,46 +866,49 @@ nsMathMLmoFrame::Stretch(nsRenderingCont
   // Before we leave... there is a last item in the check-list:
   // If our parent is not embellished, it means we are the outermost embellished
   // container and so we put the spacing, otherwise we don't include the spacing,
   // the outermost embellished container will take care of it.
 
   if (!NS_MATHML_OPERATOR_HAS_EMBELLISH_ANCESTOR(mFlags)) {
 
     // Account the spacing if we are not an accent with explicit attributes
-    nscoord leftSpace = mEmbellishData.leftSpace;
-    if (isAccent && !NS_MATHML_OPERATOR_HAS_LEFTSPACE_ATTR(mFlags)) {
-      leftSpace = 0;
+    nscoord leadingSpace = mEmbellishData.leadingSpace;
+    if (isAccent && !NS_MATHML_OPERATOR_HAS_LSPACE_ATTR(mFlags)) {
+      leadingSpace = 0;
     }
-    nscoord rightSpace = mEmbellishData.rightSpace;
-    if (isAccent && !NS_MATHML_OPERATOR_HAS_RIGHTSPACE_ATTR(mFlags)) {
-      rightSpace = 0;
+    nscoord trailingSpace = mEmbellishData.trailingSpace;
+    if (isAccent && !NS_MATHML_OPERATOR_HAS_RSPACE_ATTR(mFlags)) {
+      trailingSpace = 0;
     }
 
-    mBoundingMetrics.width += leftSpace + rightSpace;
+    mBoundingMetrics.width += leadingSpace + trailingSpace;
     aDesiredStretchSize.width = mBoundingMetrics.width;
     aDesiredStretchSize.mBoundingMetrics.width = mBoundingMetrics.width;
 
-    if (leftSpace) {
+    nscoord dx = (NS_MATHML_IS_RTL(mPresentationData.flags) ?
+                  trailingSpace : leadingSpace);
+    if (dx) {
       // adjust the offsets
-      mBoundingMetrics.leftBearing += leftSpace;
-      mBoundingMetrics.rightBearing += leftSpace;
-      aDesiredStretchSize.mBoundingMetrics.leftBearing += leftSpace;
-      aDesiredStretchSize.mBoundingMetrics.rightBearing += leftSpace;
+      mBoundingMetrics.leftBearing += dx;
+      mBoundingMetrics.rightBearing += dx;
+      aDesiredStretchSize.mBoundingMetrics.leftBearing += dx;
+      aDesiredStretchSize.mBoundingMetrics.rightBearing += dx;
 
       if (useMathMLChar) {
         nsRect rect;
         mMathMLChar.GetRect(rect);
-        mMathMLChar.SetRect(nsRect(rect.x + leftSpace, rect.y, rect.width, rect.height));
+        mMathMLChar.SetRect(nsRect(rect.x + dx, rect.y,
+                                   rect.width, rect.height));
       }
       else {
         nsIFrame* childFrame = firstChild;
         while (childFrame) {
-          childFrame->SetPosition(childFrame->GetPosition()
-				  + nsPoint(leftSpace, 0));
+          childFrame->SetPosition(childFrame->GetPosition() +
+                                  nsPoint(dx, 0));
           childFrame = childFrame->GetNextSibling();
         }
       }
     }
   }
 
   // Finished with these:
   ClearSavedChildMetrics();
@@ -1006,20 +1009,20 @@ nsMathMLmoFrame::GetIntrinsicWidth(nsRen
       GetMaxWidth(PresContext(), *aRenderingContext,
                   stretchHint, mMaxSize,
                   NS_MATHML_OPERATOR_MAXSIZE_IS_ABSOLUTE(mFlags));
   }
   else {
     width = nsMathMLTokenFrame::GetIntrinsicWidth(aRenderingContext);
   }
 
-  // leftSpace and rightSpace are actually applied to the outermost
+  // leadingSpace and trailingSpace are actually applied to the outermost
   // embellished container but for determining total intrinsic width it should
   // be safe to include it for the core here instead.
-  width += mEmbellishData.leftSpace + mEmbellishData.rightSpace;
+  width += mEmbellishData.leadingSpace + mEmbellishData.trailingSpace;
 
   return width;
 }
 
 NS_IMETHODIMP
 nsMathMLmoFrame::AttributeChanged(PRInt32         aNameSpaceID,
                                   nsIAtom*        aAttribute,
                                   PRInt32         aModType)