Bug 1077515 - part 3 - Change desiredX (nscoord) to desiredPos (nsPoint) in nsPeekOffsetStruct, to support maintaining either vertical or horizontal position on inter-line moves. r=roc
authorJonathan Kew <jkew@mozilla.com>
Sat, 22 Nov 2014 14:39:03 +0000
changeset 216997 0c5bb0328ec8e27b713362bed0608ce92a4477b4
parent 216996 d779e840b21482086e0b1829fc109de7b2f03a47
child 216998 b51ce3f8031115d228f3660d1456de7a31fd2167
push id27871
push usercbook@mozilla.com
push dateMon, 24 Nov 2014 12:32:57 +0000
treeherdermozilla-central@b8e1741b7d5c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc
bugs1077515
milestone36.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
Bug 1077515 - part 3 - Change desiredX (nscoord) to desiredPos (nsPoint) in nsPeekOffsetStruct, to support maintaining either vertical or horizontal position on inter-line moves. r=roc
accessible/generic/HyperTextAccessible.cpp
layout/base/SelectionCarets.cpp
layout/base/nsCaret.cpp
layout/generic/nsFrame.cpp
layout/generic/nsFrameSelection.h
layout/generic/nsILineIterator.h
layout/generic/nsLineBox.cpp
layout/generic/nsLineBox.h
layout/generic/nsSelection.cpp
layout/tables/nsTableRowGroupFrame.cpp
layout/tables/nsTableRowGroupFrame.h
--- a/accessible/generic/HyperTextAccessible.cpp
+++ b/accessible/generic/HyperTextAccessible.cpp
@@ -503,17 +503,17 @@ HyperTextAccessible::FindOffset(uint32_t
                                             &unusedOffsetInFrame,
                                             &frameAtOffset);
 
   const bool kIsJumpLinesOk = true; // okay to jump lines
   const bool kIsScrollViewAStop = false; // do not stop at scroll views
   const bool kIsKeyboardSelect = true; // is keyboard selection
   const bool kIsVisualBidi = false; // use visual order for bidi text
   nsPeekOffsetStruct pos(aAmount, aDirection, innerContentOffset,
-                         0, kIsJumpLinesOk, kIsScrollViewAStop,
+                         nsPoint(0, 0), kIsJumpLinesOk, kIsScrollViewAStop,
                          kIsKeyboardSelect, kIsVisualBidi,
                          aWordMovementType);
   nsresult rv = frameAtOffset->PeekOffset(&pos);
 
   // PeekOffset fails on last/first lines of the text in certain cases.
   if (NS_FAILED(rv) && aAmount == eSelectLine) {
     pos.mAmount = (aDirection == eDirNext) ? eSelectEndLine : eSelectBeginLine;
     frameAtOffset->PeekOffset(&pos);
--- a/layout/base/SelectionCarets.cpp
+++ b/layout/base/SelectionCarets.cpp
@@ -630,17 +630,17 @@ CompareRangeWithContentOffset(nsRange* a
   if (!theFrame) {
     return false;
   }
 
   // Move one character forward/backward from point and get offset
   nsPeekOffsetStruct pos(eSelectCluster,
                          dir,
                          offset,
-                         0,
+                         nsPoint(0, 0),
                          true,
                          true,  //limit on scrolled views
                          false,
                          false);
   nsresult rv = theFrame->PeekOffset(&pos);
   if (NS_FAILED(rv)) {
     pos.mResultContent = content;
     pos.mContentOffset = nodeOffset;
--- a/layout/base/nsCaret.cpp
+++ b/layout/base/nsCaret.cpp
@@ -695,17 +695,19 @@ nsCaret::GetCaretFrameForNodeOffset(nsFr
               {
                 // if there is no frameBefore, we must be at the beginning of the line
                 // so we stay with the current frame.
                 // Exception: when the first frame on the line has a different Bidi level from the paragraph level, there is no
                 // real frame for the caret to be in. We have to find the visually first frame on the line.
                 nsBidiLevel baseLevel = NS_GET_BASE_LEVEL(frameAfter);
                 if (baseLevel != levelAfter)
                 {
-                  nsPeekOffsetStruct pos(eSelectBeginLine, eDirPrevious, 0, 0, false, true, false, true);
+                  nsPeekOffsetStruct pos(eSelectBeginLine, eDirPrevious, 0,
+                                         nsPoint(0, 0), false, true, false,
+                                         true);
                   if (NS_SUCCEEDED(frameAfter->PeekOffset(&pos))) {
                     theFrame = pos.mResultFrame;
                     theFrameOffset = pos.mContentOffset;
                   }
                 }
               }
             }
           }
@@ -728,17 +730,19 @@ nsCaret::GetCaretFrameForNodeOffset(nsFr
               {
                 // if there is no frameAfter, we must be at the end of the line
                 // so we stay with the current frame.
                 // Exception: when the last frame on the line has a different Bidi level from the paragraph level, there is no
                 // real frame for the caret to be in. We have to find the visually last frame on the line.
                 nsBidiLevel baseLevel = NS_GET_BASE_LEVEL(frameBefore);
                 if (baseLevel != levelBefore)
                 {
-                  nsPeekOffsetStruct pos(eSelectEndLine, eDirNext, 0, 0, false, true, false, true);
+                  nsPeekOffsetStruct pos(eSelectEndLine, eDirNext, 0,
+                                         nsPoint(0, 0), false, true, false,
+                                         true);
                   if (NS_SUCCEEDED(frameBefore->PeekOffset(&pos))) {
                     theFrame = pos.mResultFrame;
                     theFrameOffset = pos.mContentOffset;
                   }
                 }
               }
             }
           }
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -3086,45 +3086,45 @@ nsFrame::PeekBackwardAndForward(nsSelect
   nsresult rv;
 
   if (aAmountBack == eSelectWord) {
     // To avoid selecting the previous word when at start of word,
     // first move one character forward.
     nsPeekOffsetStruct pos(eSelectCharacter,
                            eDirNext,
                            aStartPos,
-                           0,
+                           nsPoint(0, 0),
                            aJumpLines,
                            true,  //limit on scrolled views
                            false,
                            false);
     rv = PeekOffset(&pos);
     if (NS_SUCCEEDED(rv)) {
       baseFrame = pos.mResultFrame;
       baseOffset = pos.mContentOffset;
     }
   }
 
   // Use peek offset one way then the other:
   nsPeekOffsetStruct startpos(aAmountBack,
                               eDirPrevious,
                               baseOffset,
-                              0,
+                              nsPoint(0, 0),
                               aJumpLines,
                               true,  //limit on scrolled views
                               false,
                               false);
   rv = baseFrame->PeekOffset(&startpos);
   if (NS_FAILED(rv))
     return rv;
 
   nsPeekOffsetStruct endpos(aAmountForward,
                             eDirNext,
                             aStartPos,
-                            0,
+                            nsPoint(0, 0),
                             aJumpLines,
                             true,  //limit on scrolled views
                             false,
                             false);
   rv = PeekOffset(&endpos);
   if (NS_FAILED(rv))
     return rv;
 
@@ -6079,18 +6079,20 @@ nsFrame::GetNextPrevLineFromeBlockFrame(
       }
       else{
         nearStoppingFrame = lastFrame;
         farStoppingFrame = firstFrame;
       }
       nsPoint offset;
       nsView * view; //used for call of get offset from view
       aBlockFrame->GetOffsetFromView(offset,&view);
-      nscoord newDesiredX  = aPos->mDesiredX - offset.x;//get desired x into blockframe coordinates!
-      result = it->FindFrameAt(searchingLine, newDesiredX, &resultFrame, &isBeforeFirstFrame, &isAfterLastFrame);
+      nsPoint newDesiredPos =
+        aPos->mDesiredPos - offset; //get desired position into blockframe coords
+      result = it->FindFrameAt(searchingLine, newDesiredPos, &resultFrame,
+                               &isBeforeFirstFrame, &isAfterLastFrame);
       if(NS_FAILED(result))
         continue;
     }
 
     if (NS_SUCCEEDED(result) && resultFrame)
     {
       //check to see if this is ANOTHER blockframe inside the other one if so then call into its lines
       nsAutoLineIterator newIt = resultFrame->GetLineIterator();
@@ -6111,26 +6113,30 @@ nsFrame::GetNextPrevLineFromeBlockFrame(
                                     false     // aFollowOOFs
                                     );
       if (NS_FAILED(result))
         return result;
 
       nsIFrame *storeOldResultFrame = resultFrame;
       while ( !found ){
         nsPoint point;
-        point.x = aPos->mDesiredX;
-
         nsRect tempRect = resultFrame->GetRect();
         nsPoint offset;
         nsView * view; //used for call of get offset from view
         resultFrame->GetOffsetFromView(offset, &view);
         if (!view) {
           return NS_ERROR_FAILURE;
         }
-        point.y = tempRect.height + offset.y;
+        if (resultFrame->GetWritingMode().IsVertical()) {
+          point.y = aPos->mDesiredPos.y;
+          point.x = tempRect.width + offset.x;
+        } else {
+          point.y = tempRect.height + offset.y;
+          point.x = aPos->mDesiredPos.x;
+        }
 
         //special check. if we allow non-text selection then we can allow a hit location to fall before a table.
         //otherwise there is no way to get and click signal to fall before a table (it being a line iterator itself)
         nsIPresShell *shell = aPresContext->GetPresShell();
         if (!shell)
           return NS_ERROR_FAILURE;
         int16_t isEditor = shell->GetSelectionFlags();
         isEditor = isEditor == nsISelectionDisplay::DISPLAY_ALL;
@@ -6203,17 +6209,17 @@ nsFrame::GetNextPrevLineFromeBlockFrame(
                                       aPresContext, resultFrame,
                                       eLeaf,
                                       false, // aVisual
                                       aPos->mScrollViewStop,
                                       false     // aFollowOOFs
                                       );
       }
       while ( !found ){
-        nsPoint point(aPos->mDesiredX, 0);
+        nsPoint point = aPos->mDesiredPos;
         nsView* view;
         nsPoint offset;
         resultFrame->GetOffsetFromView(offset, &view);
         ContentOffsets offsets =
             resultFrame->GetContentOffsetsFromPoint(point - offset);
         aPos->mResultContent = offsets.content;
         aPos->mContentOffset = offsets.offset;
         aPos->mAttach = offsets.associate;
--- a/layout/generic/nsFrameSelection.h
+++ b/layout/generic/nsFrameSelection.h
@@ -58,17 +58,17 @@ class nsIScrollableFrame;
  *  that are passed to nsFrame::PeekOffset(). See below for the description of
  *  individual arguments.
  */
 struct MOZ_STACK_CLASS nsPeekOffsetStruct
 {
   nsPeekOffsetStruct(nsSelectionAmount aAmount,
                      nsDirection aDirection,
                      int32_t aStartOffset,
-                     nscoord aDesiredX,
+                     nsPoint aDesiredPos,
                      bool aJumpLines,
                      bool aScrollViewStop,
                      bool aIsKeyboardSelect,
                      bool aVisual,
                      mozilla::EWordMovementType aWordMovementType = mozilla::eDefaultBehavior);
 
   // Note: Most arguments (input and output) are only used with certain values
   // of mAmount. These values are indicated for each argument below.
@@ -91,19 +91,20 @@ struct MOZ_STACK_CLASS nsPeekOffsetStruc
   //             of the next paragraph".
   //             Used with: eSelectCharacter, eSelectWord, eSelectLine, eSelectParagraph.
   nsDirection mDirection;
 
   // mStartOffset: Offset into the content of the current frame where the peek starts.
   //               Used with: eSelectCharacter, eSelectWord
   int32_t mStartOffset;
   
-  // mDesiredX: The desired x coordinate for the caret.
-  //            Used with: eSelectLine.
-  nscoord mDesiredX;
+  // mDesiredPos: The desired inline coordinate for the caret
+  //              (one of .x or .y will be used, depending on line's writing mode)
+  //              Used with: eSelectLine.
+  nsPoint mDesiredPos;
 
   // mWordMovementType: An enum that determines whether to prefer the start or end of a word
   //                    or to use the default beahvior, which is a combination of 
   //                    direction and the platform-based pref
   //                    "layout.word_select.eat_space_to_next_word"
   mozilla::EWordMovementType mWordMovementType;
 
   // mJumpLines: Whether to allow jumping across line boundaries.
@@ -640,19 +641,19 @@ private:
     eLogical,
     eVisual,
     eUsePrefStyle
   };
   nsresult     MoveCaret(nsDirection aDirection, bool aContinueSelection,
                          nsSelectionAmount aAmount,
                          CaretMovementStyle aMovementStyle);
 
-  nsresult     FetchDesiredX(nscoord &aDesiredX); //the x position requested by the Key Handling for up down
-  void         InvalidateDesiredX(); //do not listen to mDesiredX you must get another.
-  void         SetDesiredX(nscoord aX); //set the mDesiredX
+  nsresult     FetchDesiredPos(nsPoint &aDesiredPos); //the position requested by the Key Handling for up down
+  void         InvalidateDesiredPos(); //do not listen to mDesiredPos you must get another.
+  void         SetDesiredPos(nsPoint aPos); //set the mDesiredPos
 
   uint32_t     GetBatching() const {return mBatching; }
   bool         GetNotifyFrames() const { return mNotifyFrames; }
   void         SetDirty(bool aDirty=true){if (mBatching) mChangesDuringBatching = aDirty;}
 
   // nsFrameSelection may get deleted when calling this,
   // so remember to use nsCOMPtr when needed.
   nsresult     NotifySelectionListeners(SelectionType aType);     // add parameters to say collapsed etc?
@@ -709,24 +710,24 @@ private:
   nsIPresShell *mShell;
 
   int16_t mSelectionChangeReason; // reason for notifications of selection changing
   int16_t mDisplaySelection; //for visual display purposes.
 
   CaretAssociateHint mHint;   //hint to tell if the selection is at the end of this line or beginning of next
   nsBidiLevel mCaretBidiLevel;
 
-  int32_t mDesiredX;
+  nsPoint mDesiredPos;
   uint32_t mDelayedMouseEventClickCount;
   bool mDelayedMouseEventIsShift;
   bool mDelayedMouseEventValid;
 
   bool mChangesDuringBatching;
   bool mNotifyFrames;
   bool mDragSelectingCells;
   bool mDragState;   //for drag purposes
   bool mMouseDoubleDownState; //has the doubleclick down happened
-  bool mDesiredXSet;
+  bool mDesiredPosSet;
 
   int8_t mCaretMovementStyle;
 };
 
 #endif /* nsFrameSelection_h___ */
--- a/layout/generic/nsILineIterator.h
+++ b/layout/generic/nsILineIterator.h
@@ -1,17 +1,17 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* 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/. */
 #ifndef nsILineIterator_h___
 #define nsILineIterator_h___
 
 #include "nscore.h"
-#include "nsCoord.h"
+#include "nsPoint.h"
 #include "mozilla/Attributes.h"
 
 class nsIFrame;
 struct nsRect;
 
 // Line Flags (see GetLine below)
 
 // This bit is set when the line is wrapping up a block frame. When
@@ -77,25 +77,26 @@ public:
    * Given a frame that's a child of the block, find which line its on
    * and return that line index, as long as it's at least as big as
    * aStartLine.  Returns -1 if the frame cannot be found on lines
    * starting with aStartLine.
    */
   virtual int32_t FindLineContaining(nsIFrame* aFrame,
                                      int32_t aStartLine = 0) = 0;
 
-  // Given a line number and an X coordinate, find the frame on the
-  // line that is nearest to the X coordinate. The
-  // aXIsBeforeFirstFrame and aXIsAfterLastFrame flags are updated
+  // Given a line number and a coordinate, find the frame on the line
+  // that is nearest to aPos along the inline axis. (The block-axis coord
+  // of aPos is irrelevant.)
+  // The aPosIsBeforeFirstFrame and aPosIsAfterLastFrame flags are updated
   // appropriately.
   NS_IMETHOD FindFrameAt(int32_t aLineNumber,
-                         nscoord aX,
+                         nsPoint aPos,
                          nsIFrame** aFrameFound,
-                         bool* aXIsBeforeFirstFrame,
-                         bool* aXIsAfterLastFrame) = 0;
+                         bool* aPosIsBeforeFirstFrame,
+                         bool* aPosIsAfterLastFrame) = 0;
 
   // Give the line iterator implementor a chance todo something more complicated than
   // nsIFrame::GetNextSibling()
   NS_IMETHOD GetNextSiblingOnLine(nsIFrame*& aFrame, int32_t aLineNumber) = 0;
 
   // Check whether visual and logical order of frames within a line are identical.
   //  If not, return the first and last visual frames
   NS_IMETHOD CheckLineOrder(int32_t                  aLine,
--- a/layout/generic/nsLineBox.cpp
+++ b/layout/generic/nsLineBox.cpp
@@ -706,87 +706,94 @@ nsLineIterator::CheckLineOrder(int32_t  
   *aFirstVisual = mRightToLeft ? rightmostFrame : leftmostFrame;
   *aLastVisual = mRightToLeft ? leftmostFrame : rightmostFrame;
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsLineIterator::FindFrameAt(int32_t aLineNumber,
-                            nscoord aX,
+                            nsPoint aPos,
                             nsIFrame** aFrameFound,
-                            bool* aXIsBeforeFirstFrame,
-                            bool* aXIsAfterLastFrame)
+                            bool* aPosIsBeforeFirstFrame,
+                            bool* aPosIsAfterLastFrame)
 {
-  NS_PRECONDITION(aFrameFound && aXIsBeforeFirstFrame && aXIsAfterLastFrame,
+  NS_PRECONDITION(aFrameFound && aPosIsBeforeFirstFrame && aPosIsAfterLastFrame,
                   "null OUT ptr");
-  if (!aFrameFound || !aXIsBeforeFirstFrame || !aXIsAfterLastFrame) {
+  if (!aFrameFound || !aPosIsBeforeFirstFrame || !aPosIsAfterLastFrame) {
     return NS_ERROR_NULL_POINTER;
   }
   if ((aLineNumber < 0) || (aLineNumber >= mNumLines)) {
     return NS_ERROR_INVALID_ARG;
   }
 
   nsLineBox* line = mLines[aLineNumber];
   if (!line) {
     *aFrameFound = nullptr;
-    *aXIsBeforeFirstFrame = true;
-    *aXIsAfterLastFrame = false;
+    *aPosIsBeforeFirstFrame = true;
+    *aPosIsAfterLastFrame = false;
     return NS_OK;
   }
 
   if (line->ISize() == 0 && line->BSize() == 0)
     return NS_ERROR_FAILURE;
 
   nsIFrame* frame = line->mFirstChild;
-  nsIFrame* closestFromLeft = nullptr;
-  nsIFrame* closestFromRight = nullptr;
+  nsIFrame* closestFromStart = nullptr;
+  nsIFrame* closestFromEnd = nullptr;
+
+  WritingMode wm = line->mWritingMode;
+  nscoord cw = line->mContainerWidth;
+
+  LogicalPoint pos(wm, aPos, cw);
+
   int32_t n = line->GetChildCount();
   while (n--) {
-    nsRect rect = frame->GetRect();
-    if (rect.width > 0) {
-      // If aX is inside this frame - this is it
-      if (rect.x <= aX && rect.XMost() > aX) {
-        closestFromLeft = closestFromRight = frame;
+    LogicalRect rect = frame->GetLogicalRect(wm, cw);
+    if (rect.ISize(wm) > 0) {
+      // If pos.I() is inside this frame - this is it
+      if (rect.IStart(wm) <= pos.I(wm) && rect.IEnd(wm) > pos.I(wm)) {
+        closestFromStart = closestFromEnd = frame;
         break;
       }
-      if (rect.x < aX) {
-        if (!closestFromLeft || 
-            rect.XMost() > closestFromLeft->GetRect().XMost())
-          closestFromLeft = frame;
+      if (rect.IStart(wm) < pos.I(wm)) {
+        if (!closestFromStart || 
+            rect.IEnd(wm) > closestFromStart->GetLogicalRect(wm, cw).IEnd(wm))
+          closestFromStart = frame;
       }
       else {
-        if (!closestFromRight ||
-            rect.x < closestFromRight->GetRect().x)
-          closestFromRight = frame;
+        if (!closestFromEnd ||
+            rect.IStart(wm) < closestFromEnd->GetLogicalRect(wm, cw).IStart(wm))
+          closestFromEnd = frame;
       }
     }
     frame = frame->GetNextSibling();
   }
-  if (!closestFromLeft && !closestFromRight) {
+  if (!closestFromStart && !closestFromEnd) {
     // All frames were zero-width. Just take the first one.
-    closestFromLeft = closestFromRight = line->mFirstChild;
+    closestFromStart = closestFromEnd = line->mFirstChild;
   }
-  *aXIsBeforeFirstFrame = mRightToLeft ? !closestFromRight : !closestFromLeft;
-  *aXIsAfterLastFrame = mRightToLeft ? !closestFromLeft : !closestFromRight;
-  if (closestFromLeft == closestFromRight) {
-    *aFrameFound = closestFromLeft;
+  *aPosIsBeforeFirstFrame = mRightToLeft ? !closestFromEnd : !closestFromStart;
+  *aPosIsAfterLastFrame = mRightToLeft ? !closestFromStart : !closestFromEnd;
+  if (closestFromStart == closestFromEnd) {
+    *aFrameFound = closestFromStart;
   }
-  else if (!closestFromLeft) {
-    *aFrameFound = closestFromRight;
+  else if (!closestFromStart) {
+    *aFrameFound = closestFromEnd;
   }
-  else if (!closestFromRight) {
-    *aFrameFound = closestFromLeft;
+  else if (!closestFromEnd) {
+    *aFrameFound = closestFromStart;
   }
   else { // we're between two frames
-    nscoord delta = closestFromRight->GetRect().x - closestFromLeft->GetRect().XMost();
-    if (aX < closestFromLeft->GetRect().XMost() + delta/2)
-      *aFrameFound = closestFromLeft;
+    nscoord delta = closestFromEnd->GetLogicalRect(wm, cw).IStart(wm) -
+                    closestFromStart->GetLogicalRect(wm, cw).IEnd(wm);
+    if (pos.I(wm) < closestFromStart->GetLogicalRect(wm, cw).IEnd(wm) + delta/2)
+      *aFrameFound = closestFromStart;
     else
-      *aFrameFound = closestFromRight;
+      *aFrameFound = closestFromEnd;
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsLineIterator::GetNextSiblingOnLine(nsIFrame*& aFrame, int32_t aLineNumber)
 {
   aFrame = aFrame->GetNextSibling();
--- a/layout/generic/nsLineBox.h
+++ b/layout/generic/nsLineBox.h
@@ -1700,20 +1700,20 @@ public:
   virtual bool GetDirection() MOZ_OVERRIDE;
   NS_IMETHOD GetLine(int32_t aLineNumber,
                      nsIFrame** aFirstFrameOnLine,
                      int32_t* aNumFramesOnLine,
                      nsRect& aLineBounds,
                      uint32_t* aLineFlags) MOZ_OVERRIDE;
   virtual int32_t FindLineContaining(nsIFrame* aFrame, int32_t aStartLine = 0) MOZ_OVERRIDE;
   NS_IMETHOD FindFrameAt(int32_t aLineNumber,
-                         nscoord aX,
+                         nsPoint aPos,
                          nsIFrame** aFrameFound,
-                         bool* aXIsBeforeFirstFrame,
-                         bool* aXIsAfterLastFrame) MOZ_OVERRIDE;
+                         bool* aPosIsBeforeFirstFrame,
+                         bool* aPosIsAfterLastFrame) MOZ_OVERRIDE;
 
   NS_IMETHOD GetNextSiblingOnLine(nsIFrame*& aFrame, int32_t aLineNumber) MOZ_OVERRIDE;
   NS_IMETHOD CheckLineOrder(int32_t                  aLine,
                             bool                     *aIsReordered,
                             nsIFrame                 **aFirstVisual,
                             nsIFrame                 **aLastVisual) MOZ_OVERRIDE;
   nsresult Init(nsLineList& aLines, bool aRightToLeft);
 
--- a/layout/generic/nsSelection.cpp
+++ b/layout/generic/nsSelection.cpp
@@ -43,17 +43,16 @@ static NS_DEFINE_CID(kFrameTraversalCID,
 
 #include "nsIDOMText.h"
 
 #include "nsContentUtils.h"
 #include "nsThreadUtils.h"
 #include "mozilla/Preferences.h"
 #include "nsDOMClassInfoID.h"
 
-//included for desired x position;
 #include "nsPresContext.h"
 #include "nsIPresShell.h"
 #include "nsCaret.h"
 #include "TouchCaret.h"
 #include "SelectionCarets.h"
 
 #include "mozilla/MouseEvents.h"
 #include "mozilla/TextEvents.h"
@@ -103,26 +102,26 @@ static void printRange(nsRange *aDomRang
 //#define DEBUG_NAVIGATION
 
 
 //#define DEBUG_TABLE_SELECTION 1
 
 nsPeekOffsetStruct::nsPeekOffsetStruct(nsSelectionAmount aAmount,
                                        nsDirection aDirection,
                                        int32_t aStartOffset,
-                                       nscoord aDesiredX,
+                                       nsPoint aDesiredPos,
                                        bool aJumpLines,
                                        bool aScrollViewStop,
                                        bool aIsKeyboardSelect,
                                        bool aVisual,
                                        EWordMovementType aWordMovementType)
   : mAmount(aAmount)
   , mDirection(aDirection)
   , mStartOffset(aStartOffset)
-  , mDesiredX(aDesiredX)
+  , mDesiredPos(aDesiredPos)
   , mWordMovementType(aWordMovementType)
   , mJumpLines(aJumpLines)
   , mScrollViewStop(aScrollViewStop)
   , mIsKeyboardSelect(aIsKeyboardSelect)
   , mVisual(aVisual)
   , mResultContent()
   , mResultFrame(nullptr)
   , mContentOffset(0)
@@ -431,67 +430,65 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mMaintainRange)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mLimiter)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mAncestorLimiter)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(nsFrameSelection, AddRef)
 NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(nsFrameSelection, Release)
 
-
+// Get the x (or y, in vertical writing mode) position requested
+// by the Key Handling for line-up/down
 nsresult
-nsFrameSelection::FetchDesiredX(nscoord &aDesiredX) //the x position requested by the Key Handling for up down
-{
-  if (!mShell)
-  {
-    NS_ERROR("fetch desired X failed");
+nsFrameSelection::FetchDesiredPos(nsPoint &aDesiredPos)
+{
+  if (!mShell) {
+    NS_ERROR("fetch desired position failed");
     return NS_ERROR_FAILURE;
   }
-  if (mDesiredXSet)
-  {
-    aDesiredX = mDesiredX;
+  if (mDesiredPosSet) {
+    aDesiredPos = mDesiredPos;
     return NS_OK;
   }
 
   nsRefPtr<nsCaret> caret = mShell->GetCaret();
-  if (!caret)
+  if (!caret) {
     return NS_ERROR_NULL_POINTER;
+  }
 
   int8_t index = GetIndexFromSelectionType(nsISelectionController::SELECTION_NORMAL);
   caret->SetSelection(mDomSelections[index]);
 
   nsRect coord;
   nsIFrame* caretFrame = caret->GetGeometry(&coord);
-  if (!caretFrame)
+  if (!caretFrame) {
     return NS_ERROR_FAILURE;
+  }
   nsPoint viewOffset(0, 0);
   nsView* view = nullptr;
   caretFrame->GetOffsetFromView(viewOffset, &view);
-  if (view)
-    coord.x += viewOffset.x;
-
-  aDesiredX = coord.x;
+  if (view) {
+    coord += viewOffset;
+  }
+  aDesiredPos = coord.TopLeft();
   return NS_OK;
 }
 
-
-
 void
-nsFrameSelection::InvalidateDesiredX() //do not listen to mDesiredX you must get another.
-{
-  mDesiredXSet = false;
-}
-
-
+nsFrameSelection::InvalidateDesiredPos() // do not listen to mDesiredPos;
+                                         // you must get another.
+{
+  mDesiredPosSet = false;
+}
 
 void
-nsFrameSelection::SetDesiredX(nscoord aX) //set the mDesiredX
-{
-  mDesiredX = aX;
-  mDesiredXSet = true;
+nsFrameSelection::SetDesiredPos(nsPoint aPos)
+{
+  mDesiredPos = aPos;
+  mDesiredPosSet = true;
 }
 
 nsresult
 nsFrameSelection::ConstrainFrameAndPointToAnchorSubtree(nsIFrame  *aFrame,
                                                         nsPoint&   aPoint,
                                                         nsIFrame **aRetFrame,
                                                         nsPoint&   aRetPoint)
 {
@@ -713,17 +710,17 @@ GetCellParent(nsINode *aDomNode)
     return nullptr;
 }
 
 void
 nsFrameSelection::Init(nsIPresShell *aShell, nsIContent *aLimiter)
 {
   mShell = aShell;
   mDragState = false;
-  mDesiredXSet = false;
+  mDesiredPosSet = false;
   mLimiter = aLimiter;
   mCaretMovementStyle =
     Preferences::GetInt("bidi.edit.caret_movement_style", 2);
   // Set touch caret as selection listener
   nsRefPtr<TouchCaret> touchCaret = mShell->GetTouchCaret();
   if (touchCaret) {
     int8_t index = GetIndexFromSelectionType(nsISelectionController::SELECTION_NORMAL);
     if (mDomSelections[index]) {
@@ -761,17 +758,17 @@ nsFrameSelection::MoveCaret(nsDirection 
     return NS_OK;
   }
 
   nsPresContext *context = mShell->GetPresContext();
   if (!context)
     return NS_ERROR_FAILURE;
 
   bool isCollapsed;
-  nscoord desiredX = 0; //we must keep this around and revalidate it when its just UP/DOWN
+  nsPoint desiredPos(0, 0); //we must keep this around and revalidate it when its just UP/DOWN
 
   int8_t index = GetIndexFromSelectionType(nsISelectionController::SELECTION_NORMAL);
   nsRefPtr<Selection> sel = mDomSelections[index];
   if (!sel)
     return NS_ERROR_NULL_POINTER;
 
   int32_t scrollFlags = 0;
   nsINode* focusNode = sel->GetFocusNode();
@@ -781,23 +778,25 @@ nsFrameSelection::MoveCaret(nsDirection 
         focusNode->AsElement()->State().
           HasState(NS_EVENT_STATE_MOZ_READWRITE)))) {
     // If caret moves in editor, it should cause scrolling even if it's in
     // overflow: hidden;.
     scrollFlags |= Selection::SCROLL_OVERFLOW_HIDDEN;
   }
 
   nsresult result = sel->GetIsCollapsed(&isCollapsed);
-  if (NS_FAILED(result))
+  if (NS_FAILED(result)) {
     return result;
+  }
   if (aAmount == eSelectLine) {
-    result = FetchDesiredX(desiredX);
-    if (NS_FAILED(result))
+    result = FetchDesiredPos(desiredPos);
+    if (NS_FAILED(result)) {
       return result;
-    SetDesiredX(desiredX);
+    }
+    SetDesiredPos(desiredPos);
   }
 
   int32_t caretStyle = Preferences::GetInt("layout.selection.caret_style", 0);
   if (caretStyle == 0
 #ifdef XP_WIN
       && aAmount != eSelectLine
 #endif
      ) {
@@ -845,39 +844,39 @@ nsFrameSelection::MoveCaret(nsDirection 
   result = sel->GetPrimaryFrameForFocusNode(&frame, &offsetused,
                                             visualMovement);
 
   if (NS_FAILED(result) || !frame)
     return NS_FAILED(result) ? result : NS_ERROR_FAILURE;
 
   //set data using mLimiter to stop on scroll views.  If we have a limiter then we stop peeking
   //when we hit scrollable views.  If no limiter then just let it go ahead
-  nsPeekOffsetStruct pos(aAmount, eDirPrevious, offsetused, desiredX,
+  nsPeekOffsetStruct pos(aAmount, eDirPrevious, offsetused, desiredPos,
                          true, mLimiter != nullptr, true, visualMovement);
 
   nsBidiDirection paraDir = nsBidiPresUtils::ParagraphDirection(frame);
 
   CaretAssociateHint tHint(mHint); //temporary variable so we dont set mHint until it is necessary
   switch (aAmount){
    case eSelectCharacter:
     case eSelectCluster:
     case eSelectWord:
     case eSelectWordNoSpace:
-      InvalidateDesiredX();
+      InvalidateDesiredPos();
       pos.mAmount = aAmount;
       pos.mDirection = (visualMovement && paraDir == NSBIDI_RTL)
                        ? nsDirection(1 - aDirection) : aDirection;
       break;
     case eSelectLine:
       pos.mAmount = aAmount;
       pos.mDirection = aDirection;
       break;
     case eSelectBeginLine:
     case eSelectEndLine:
-      InvalidateDesiredX();
+      InvalidateDesiredPos();
       pos.mAmount = aAmount;
       pos.mDirection = (visualMovement && paraDir == NSBIDI_RTL)
                        ? nsDirection(1 - aDirection) : aDirection;
       break;
     default:
       return NS_ERROR_FAILURE;
   }
   PostReason(nsISelectionListener::KEYPRESS_REASON);
@@ -1364,17 +1363,17 @@ nsFrameSelection::HandleClick(nsIContent
                               uint32_t           aContentEndOffset,
                               bool               aContinueSelection,
                               bool               aMultipleSelection,
                               CaretAssociateHint aHint)
 {
   if (!aNewFocus)
     return NS_ERROR_INVALID_ARG;
 
-  InvalidateDesiredX();
+  InvalidateDesiredPos();
 
   if (!aContinueSelection) {
     mMaintainRange = nullptr;
     if (!IsValidSelectionPoint(this, aNewFocus)) {
       mAncestorLimiter = nullptr;
     }
   }
 
@@ -1436,25 +1435,26 @@ nsFrameSelection::HandleDrag(nsIFrame *a
 
     int32_t offset;
     nsIFrame* frame = GetFrameForNodeOffset(offsets.content, offsets.offset,
         CARET_ASSOCIATE_AFTER, &offset);
 
     if (frame && amount == eSelectWord && direction == eDirPrevious) {
       // To avoid selecting the previous word when at start of word,
       // first move one character forward.
-      nsPeekOffsetStruct charPos(eSelectCharacter, eDirNext, offset, 0,
-                                 false, mLimiter != nullptr, false, false);
+      nsPeekOffsetStruct charPos(eSelectCharacter, eDirNext, offset,
+                                 nsPoint(0, 0), false, mLimiter != nullptr,
+                                 false, false);
       if (NS_SUCCEEDED(frame->PeekOffset(&charPos))) {
         frame = charPos.mResultFrame;
         offset = charPos.mContentOffset;
       }
     }
 
-    nsPeekOffsetStruct pos(amount, direction, offset, 0,
+    nsPeekOffsetStruct pos(amount, direction, offset, nsPoint(0, 0),
                            false, mLimiter != nullptr, false, false);
 
     if (frame && NS_SUCCEEDED(frame->PeekOffset(&pos)) && pos.mResultContent) {
       offsets.content = pos.mResultContent;
       offsets.offset = pos.mContentOffset;
     }
   }
   
@@ -1533,27 +1533,26 @@ nsFrameSelection::TakeFocus(nsIContent* 
 
       nsRefPtr<nsRange> newRange = new nsRange(aNewFocus);
 
       newRange->SetStart(aNewFocus, aContentOffset);
       newRange->SetEnd(aNewFocus, aContentOffset);
       mDomSelections[index]->AddRange(newRange);
       mBatching = batching;
       mChangesDuringBatching = changes;
-    }
-    else
-    {
-      bool oldDesiredXSet = mDesiredXSet; //need to keep old desired X if it was set.
+    } else {
+      bool oldDesiredPosSet = mDesiredPosSet; //need to keep old desired position if it was set.
       mDomSelections[index]->Collapse(aNewFocus, aContentOffset);
-      mDesiredXSet = oldDesiredXSet; //now reset desired X back.
+      mDesiredPosSet = oldDesiredPosSet; //now reset desired pos back.
       mBatching = batching;
       mChangesDuringBatching = changes;
     }
-    if (aContentEndOffset != aContentOffset)
+    if (aContentEndOffset != aContentOffset) {
       mDomSelections[index]->Extend(aNewFocus, aContentEndOffset);
+    }
 
     //find out if we are inside a table. if so, find out which one and which cell
     //once we do that, the next time we get a takefocus, check the parent tree. 
     //if we are no longer inside same table ,cell then switch to table selection mode.
     // BUT only do this in an editor
 
     NS_ENSURE_STATE(mShell);
     int16_t displaySelection = mShell->GetSelectionFlags();
@@ -1852,20 +1851,21 @@ nsFrameSelection::CommonPageMove(bool aF
 
   //get the frame from the scrollable view
 
   nsIFrame* scrolledFrame = aScrollableFrame->GetScrolledFrame();
   if (!scrolledFrame)
     return;
 
   // find out where the caret is.
-  // we should know mDesiredX value of nsFrameSelection, but I havent seen that behavior in other windows applications yet.
+  // we should know mDesiredPos value of nsFrameSelection, but I havent seen that behavior in other windows applications yet.
   nsISelection* domSel = GetSelection(nsISelectionController::SELECTION_NORMAL);
-  if (!domSel) 
+  if (!domSel) {
     return;
+  }
 
   nsRect caretPos;
   nsIFrame* caretFrame = nsCaret::GetGeometry(domSel, &caretPos);
   if (!caretFrame) 
     return;
   
   //need to adjust caret jump by percentage scroll
   nsSize scrollDelta = aScrollableFrame->GetPageScrollAmount();
@@ -4587,17 +4587,17 @@ Selection::Collapse(nsINode& aParentNode
 {
   if (!mFrameSelection) {
     aRv.Throw(NS_ERROR_NOT_INITIALIZED); // Can't do selection
     return;
   }
 
   nsCOMPtr<nsINode> kungfuDeathGrip = &aParentNode;
 
-  mFrameSelection->InvalidateDesiredX();
+  mFrameSelection->InvalidateDesiredPos();
   if (!IsValidSelectionPoint(mFrameSelection, &aParentNode)) {
     aRv.Throw(NS_ERROR_FAILURE);
     return;
   }
   nsresult result;
 
   nsRefPtr<nsPresContext> presContext = GetPresContext();
   if (!presContext || presContext->Document() != aParentNode.OwnerDoc()) {
@@ -5882,19 +5882,19 @@ Selection::SelectionLanguageChange(bool 
     // if cursor is between characters with opposite orientations, changing the keyboard language must change
     //  the cursor level to that of the adjacent character with the orientation corresponding to the new language.
     if (IS_LEVEL_RTL(levelBefore) == aLangRTL)
       mFrameSelection->SetCaretBidiLevel(levelBefore);
     else
       mFrameSelection->SetCaretBidiLevel(levelAfter);
   }
   
-  // The caret might have moved, so invalidate the desired X position
+  // The caret might have moved, so invalidate the desired position
   // for future usages of up-arrow or down-arrow
-  mFrameSelection->InvalidateDesiredX();
+  mFrameSelection->InvalidateDesiredPos();
   
   return NS_OK;
 }
 
 NS_IMETHODIMP_(nsDirection)
 Selection::GetSelectionDirection() {
   return mDirection;
 }
--- a/layout/tables/nsTableRowGroupFrame.cpp
+++ b/layout/tables/nsTableRowGroupFrame.cpp
@@ -1727,94 +1727,99 @@ nsTableRowGroupFrame::CheckLineOrder(int
   *aIsReordered = false;
   *aFirstVisual = nullptr;
   *aLastVisual = nullptr;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsTableRowGroupFrame::FindFrameAt(int32_t    aLineNumber, 
-                                  nscoord    aX, 
+                                  nsPoint    aPos, 
                                   nsIFrame** aFrameFound,
-                                  bool*    aXIsBeforeFirstFrame, 
-                                  bool*    aXIsAfterLastFrame)
+                                  bool*    aPosIsBeforeFirstFrame, 
+                                  bool*    aPosIsAfterLastFrame)
 {
-   nsTableFrame* table = nsTableFrame::GetTableFrame(this);
-   nsTableCellMap* cellMap = table->GetCellMap();
-   
-   *aFrameFound = nullptr;
-   *aXIsBeforeFirstFrame = true;
-   *aXIsAfterLastFrame = false;
+  nsTableFrame* table = nsTableFrame::GetTableFrame(this);
+  nsTableCellMap* cellMap = table->GetCellMap();
+
+  WritingMode wm = table->GetWritingMode();
+  nscoord cw = table->GetRect().width;
+  LogicalPoint pos(wm, aPos, cw);
+  
+  *aFrameFound = nullptr;
+  *aPosIsBeforeFirstFrame = true;
+  *aPosIsAfterLastFrame = false;
 
-   aLineNumber += GetStartRowIndex();
-   int32_t numCells = cellMap->GetNumCellsOriginatingInRow(aLineNumber);
-   if (numCells == 0) {
-     return NS_OK;
-   }
+  aLineNumber += GetStartRowIndex();
+  int32_t numCells = cellMap->GetNumCellsOriginatingInRow(aLineNumber);
+  if (numCells == 0) {
+    return NS_OK;
+  }
+  
+  nsIFrame* frame = nullptr;
+  int32_t colCount = table->GetColCount();
+  for (int32_t i = 0; i < colCount; i++) {
+    CellData* data = cellMap->GetDataAt(aLineNumber, i);
+    if (data && data->IsOrig()) {
+      frame = (nsIFrame*)data->GetCellFrame();
+      break;
+    }
+  }
+  NS_ASSERTION(frame, "cellmap is lying");
+  bool isRTL = (NS_STYLE_DIRECTION_RTL ==
+                  table->StyleVisibility()->mDirection);
   
-   nsIFrame* frame = nullptr;
-   int32_t colCount = table->GetColCount();
-   for (int32_t i = 0; i < colCount; i++) {
-     CellData* data = cellMap->GetDataAt(aLineNumber, i);
-     if (data && data->IsOrig()) {
-       frame = (nsIFrame*)data->GetCellFrame();
-       break;
-     }
-   }
-   NS_ASSERTION(frame, "cellmap is lying");
-   bool isRTL = (NS_STYLE_DIRECTION_RTL ==
-                   table->StyleVisibility()->mDirection);
-   
-   nsIFrame* closestFromLeft = nullptr;
-   nsIFrame* closestFromRight = nullptr;
-   int32_t n = numCells;
-   nsIFrame* firstFrame = frame;
-   while (n--) {
-     nsRect rect = frame->GetRect();
-     if (rect.width > 0) {
-       // If aX is inside this frame - this is it
-       if (rect.x <= aX && rect.XMost() > aX) {
-         closestFromLeft = closestFromRight = frame;
-         break;
-       }
-       if (rect.x < aX) {
-         if (!closestFromLeft ||
-             rect.XMost() > closestFromLeft->GetRect().XMost())
-           closestFromLeft = frame;
-       }
-       else {
-         if (!closestFromRight ||
-             rect.x < closestFromRight->GetRect().x)
-           closestFromRight = frame;
-       }
-     }
-     frame = frame->GetNextSibling();
-   }
-   if (!closestFromLeft && !closestFromRight) {
-     // All frames were zero-width. Just take the first one.
-     closestFromLeft = closestFromRight = firstFrame;
-   }
-   *aXIsBeforeFirstFrame = isRTL ? !closestFromRight : !closestFromLeft;
-   *aXIsAfterLastFrame =   isRTL ? !closestFromLeft : !closestFromRight;
-   if (closestFromLeft == closestFromRight) {
-     *aFrameFound = closestFromLeft;
-   }
-   else if (!closestFromLeft) {
-     *aFrameFound = closestFromRight;
-   }
-   else if (!closestFromRight) {
-     *aFrameFound = closestFromLeft;
-   }
-   else { // we're between two frames
-     nscoord delta = closestFromRight->GetRect().x -
-                     closestFromLeft->GetRect().XMost();
-     if (aX < closestFromLeft->GetRect().XMost() + delta/2)
-       *aFrameFound = closestFromLeft;
-     else
-       *aFrameFound = closestFromRight;
+  nsIFrame* closestFromStart = nullptr;
+  nsIFrame* closestFromEnd = nullptr;
+  int32_t n = numCells;
+  nsIFrame* firstFrame = frame;
+  while (n--) {
+    LogicalRect rect = frame->GetLogicalRect(wm, cw);
+    if (rect.ISize(wm) > 0) {
+      // If pos.I() is inside this frame - this is it
+      if (rect.IStart(wm) <= pos.I(wm) && rect.IEnd(wm) > pos.I(wm)) {
+        closestFromStart = closestFromEnd = frame;
+        break;
+      }
+      if (rect.IStart(wm) < pos.I(wm)) {
+        if (!closestFromStart ||
+            rect.IEnd(wm) > closestFromStart->GetLogicalRect(wm, cw).IEnd(wm))
+          closestFromStart = frame;
+      }
+      else {
+        if (!closestFromEnd ||
+            rect.IStart(wm) < closestFromEnd->GetLogicalRect(wm, cw).IStart(wm))
+          closestFromEnd = frame;
+      }
+    }
+    frame = frame->GetNextSibling();
+  }
+  if (!closestFromStart && !closestFromEnd) {
+    // All frames were zero-width. Just take the first one.
+    closestFromStart = closestFromEnd = firstFrame;
+  }
+  *aPosIsBeforeFirstFrame = isRTL ? !closestFromEnd : !closestFromStart;
+  *aPosIsAfterLastFrame =   isRTL ? !closestFromStart : !closestFromEnd;
+  if (closestFromStart == closestFromEnd) {
+    *aFrameFound = closestFromStart;
+  }
+  else if (!closestFromStart) {
+    *aFrameFound = closestFromEnd;
+  }
+  else if (!closestFromEnd) {
+    *aFrameFound = closestFromStart;
+  }
+  else { // we're between two frames
+    nscoord delta = closestFromEnd->GetLogicalRect(wm, cw).IStart(wm) -
+                    closestFromStart->GetLogicalRect(wm, cw).IEnd(wm);
+    if (pos.I(wm) < closestFromStart->GetLogicalRect(wm, cw).IEnd(wm) + delta/2) {
+      *aFrameFound = closestFromStart;
+    } else {
+      *aFrameFound = closestFromEnd;
+    }
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsTableRowGroupFrame::GetNextSiblingOnLine(nsIFrame*& aFrame, 
                                            int32_t    aLineNumber)
 {
--- a/layout/tables/nsTableRowGroupFrame.h
+++ b/layout/tables/nsTableRowGroupFrame.h
@@ -223,31 +223,31 @@ public:
     * @param aStartLine   - minimal index to return
     * @return               row index relative to the row group if this a row
     *                       frame and the index is at least aStartLine.
     *                       -1 if the frame cannot be found.
     */
   virtual int32_t FindLineContaining(nsIFrame* aFrame, int32_t aStartLine = 0) MOZ_OVERRIDE;
 
   /** Find the orginating cell frame on a row that is the nearest to the
-    * coordinate X.
+    * inline-dir coordinate of aPos.
     * @param aLineNumber          - the index of the row relative to the row group
-    * @param aX                   - X coordinate in twips relative to the
+    * @param aPos                 - coordinate in twips relative to the
     *                               origin of the row group
     * @param aFrameFound          - pointer to the cellframe
-    * @param aXIsBeforeFirstFrame - the point is before the first originating
+    * @param aPosIsBeforeFirstFrame - the point is before the first originating
     *                               cellframe
-    * @param aXIsAfterLastFrame   - the point is after the last originating
+    * @param aPosIsAfterLastFrame   - the point is after the last originating
     *                               cellframe
     */
   NS_IMETHOD FindFrameAt(int32_t aLineNumber,
-                         nscoord aX,
+                         nsPoint aPos,
                          nsIFrame** aFrameFound,
-                         bool* aXIsBeforeFirstFrame,
-                         bool* aXIsAfterLastFrame) MOZ_OVERRIDE;
+                         bool* aPosIsBeforeFirstFrame,
+                         bool* aPosIsAfterLastFrame) MOZ_OVERRIDE;
 
    /** Check whether visual and logical order of cell frames within a line are
      * identical. As the layout will reorder them this is always the case
      * @param aLine        - the index of the row relative to the table
      * @param aIsReordered - returns false
      * @param aFirstVisual - if the table is rtl first originating cell frame
      * @param aLastVisual  - if the table is rtl last originating cell frame
      */