Bug 1100071 patch 3: don't pass around bidi levels when we only need the direction, r=dholbert

This commit is contained in:
Simon Montagu 2014-11-20 12:45:23 +02:00
parent 6dea43f4b8
commit c9d76a21f8
5 changed files with 60 additions and 33 deletions

View File

@ -286,6 +286,30 @@ public:
*/
static nsBidiLevel GetFrameBaseLevel(nsIFrame* aFrame);
/**
* Get an nsBidiDirection representing the direction implied by the
* bidi base level of the frame.
* @return NSBIDI_LTR (left-to-right) or NSBIDI_RTL (right-to-left)
* NSBIDI_MIXED will never be returned.
*/
static nsBidiDirection ParagraphDirection(nsIFrame* aFrame) {
return DIRECTION_FROM_LEVEL(GetFrameBaseLevel(aFrame));
}
/**
* Get an nsBidiDirection representing the direction implied by the
* bidi embedding level of the frame.
* @return NSBIDI_LTR (left-to-right) or NSBIDI_RTL (right-to-left)
* NSBIDI_MIXED will never be returned.
*/
static nsBidiDirection FrameDirection(nsIFrame* aFrame) {
return DIRECTION_FROM_LEVEL(GetFrameEmbeddingLevel(aFrame));
}
static bool IsFrameInParagraphDirection(nsIFrame* aFrame) {
return ParagraphDirection(aFrame) == FrameDirection(aFrame);
}
enum Mode { MODE_DRAW, MODE_MEASURE };
/**

View File

@ -6653,11 +6653,14 @@ nsIFrame::PeekOffset(nsPeekOffsetStruct* aPos)
result = it->CheckLineOrder(thisLine, &isReordered, &firstFrame, &lastFrame);
baseFrame = endOfLine ? lastFrame : firstFrame;
if (baseFrame) {
nsBidiLevel embeddingLevel = nsBidiPresUtils::GetFrameEmbeddingLevel(baseFrame);
// If the direction of the frame on the edge is opposite to that of the line,
// we'll need to drill down to its opposite end, so reverse endOfLine.
if (IS_LEVEL_RTL(embeddingLevel) == !lineIsRTL)
bool frameIsRTL =
(nsBidiPresUtils::FrameDirection(baseFrame) == NSBIDI_RTL);
// If the direction of the frame on the edge is opposite to
// that of the line, we'll need to drill down to its opposite
// end, so reverse endOfLine.
if (frameIsRTL != lineIsRTL) {
endOfLine = !endOfLine;
}
}
} else {
it->GetLine(thisLine, &firstFrame, &lineFrameCount, usedRect, &lineFlags);
@ -6878,8 +6881,8 @@ nsIFrame::GetFrameFromDirection(nsDirection aDirection, bool aVisual,
result = it->CheckLineOrder(thisLine, &isReordered, &firstFrame, &lastFrame);
nsIFrame** framePtr = aDirection == eDirPrevious ? &firstFrame : &lastFrame;
if (*framePtr) {
nsBidiLevel embeddingLevel = nsBidiPresUtils::GetFrameEmbeddingLevel(*framePtr);
bool frameIsRTL = IS_LEVEL_RTL(embeddingLevel);
bool frameIsRTL =
(nsBidiPresUtils::FrameDirection(*framePtr) == NSBIDI_RTL);
if ((frameIsRTL == lineIsRTL) == (aDirection == eDirPrevious)) {
nsFrame::GetFirstLeaf(presContext, framePtr);
} else {

View File

@ -347,27 +347,26 @@ nsFrameList::GetPrevVisualFor(nsIFrame* aFrame) const
{
if (!mFirstChild)
return nullptr;
nsIFrame* parent = mFirstChild->GetParent();
if (!parent)
return aFrame ? aFrame->GetPrevSibling() : LastChild();
nsBidiLevel baseLevel = nsBidiPresUtils::GetFrameBaseLevel(mFirstChild);
nsBidiDirection paraDir = nsBidiPresUtils::ParagraphDirection(mFirstChild);
nsAutoLineIterator iter = parent->GetLineIterator();
if (!iter) {
if (!iter) {
// Parent is not a block Frame
if (parent->GetType() == nsGkAtoms::lineFrame) {
// Line frames are not bidi-splittable, so need to consider bidi reordering
if (baseLevel == NSBIDI_LTR) {
if (paraDir == NSBIDI_LTR) {
return nsBidiPresUtils::GetFrameToLeftOf(aFrame, mFirstChild, -1);
} else { // RTL
return nsBidiPresUtils::GetFrameToRightOf(aFrame, mFirstChild, -1);
}
} else {
// Just get the next or prev sibling, depending on block and frame direction.
nsBidiLevel frameEmbeddingLevel = nsBidiPresUtils::GetFrameEmbeddingLevel(mFirstChild);
if (IS_SAME_DIRECTION(frameEmbeddingLevel, baseLevel)) {
if (nsBidiPresUtils::IsFrameInParagraphDirection(mFirstChild)) {
return aFrame ? aFrame->GetPrevSibling() : LastChild();
} else {
return aFrame ? aFrame->GetNextSibling() : mFirstChild;
@ -396,7 +395,7 @@ nsFrameList::GetPrevVisualFor(nsIFrame* aFrame) const
if (aFrame) {
iter->GetLine(thisLine, &firstFrameOnLine, &numFramesOnLine, lineBounds, &lineFlags);
if (baseLevel == NSBIDI_LTR) {
if (paraDir == NSBIDI_LTR) {
frame = nsBidiPresUtils::GetFrameToLeftOf(aFrame, firstFrameOnLine, numFramesOnLine);
} else { // RTL
frame = nsBidiPresUtils::GetFrameToRightOf(aFrame, firstFrameOnLine, numFramesOnLine);
@ -407,7 +406,7 @@ nsFrameList::GetPrevVisualFor(nsIFrame* aFrame) const
// Get the last frame of the previous line
iter->GetLine(thisLine - 1, &firstFrameOnLine, &numFramesOnLine, lineBounds, &lineFlags);
if (baseLevel == NSBIDI_LTR) {
if (paraDir == NSBIDI_LTR) {
frame = nsBidiPresUtils::GetFrameToLeftOf(nullptr, firstFrameOnLine, numFramesOnLine);
} else { // RTL
frame = nsBidiPresUtils::GetFrameToRightOf(nullptr, firstFrameOnLine, numFramesOnLine);
@ -426,22 +425,21 @@ nsFrameList::GetNextVisualFor(nsIFrame* aFrame) const
if (!parent)
return aFrame ? aFrame->GetPrevSibling() : mFirstChild;
nsBidiLevel baseLevel = nsBidiPresUtils::GetFrameBaseLevel(mFirstChild);
nsBidiDirection paraDir = nsBidiPresUtils::ParagraphDirection(mFirstChild);
nsAutoLineIterator iter = parent->GetLineIterator();
if (!iter) {
// Parent is not a block Frame
if (parent->GetType() == nsGkAtoms::lineFrame) {
// Line frames are not bidi-splittable, so need to consider bidi reordering
if (baseLevel == NSBIDI_LTR) {
if (paraDir == NSBIDI_LTR) {
return nsBidiPresUtils::GetFrameToRightOf(aFrame, mFirstChild, -1);
} else { // RTL
return nsBidiPresUtils::GetFrameToLeftOf(aFrame, mFirstChild, -1);
}
} else {
// Just get the next or prev sibling, depending on block and frame direction.
nsBidiLevel frameEmbeddingLevel = nsBidiPresUtils::GetFrameEmbeddingLevel(mFirstChild);
if (IS_SAME_DIRECTION(frameEmbeddingLevel, baseLevel)) {
if (nsBidiPresUtils::IsFrameInParagraphDirection(mFirstChild)) {
return aFrame ? aFrame->GetNextSibling() : mFirstChild;
} else {
return aFrame ? aFrame->GetPrevSibling() : LastChild();
@ -469,20 +467,20 @@ nsFrameList::GetNextVisualFor(nsIFrame* aFrame) const
if (aFrame) {
iter->GetLine(thisLine, &firstFrameOnLine, &numFramesOnLine, lineBounds, &lineFlags);
if (baseLevel == NSBIDI_LTR) {
if (paraDir == NSBIDI_LTR) {
frame = nsBidiPresUtils::GetFrameToRightOf(aFrame, firstFrameOnLine, numFramesOnLine);
} else { // RTL
frame = nsBidiPresUtils::GetFrameToLeftOf(aFrame, firstFrameOnLine, numFramesOnLine);
}
}
int32_t numLines = iter->GetNumLines();
if (!frame && thisLine < numLines - 1) {
// Get the first frame of the next line
iter->GetLine(thisLine + 1, &firstFrameOnLine, &numFramesOnLine, lineBounds, &lineFlags);
if (baseLevel == NSBIDI_LTR) {
if (paraDir == NSBIDI_LTR) {
frame = nsBidiPresUtils::GetFrameToRightOf(nullptr, firstFrameOnLine, numFramesOnLine);
} else { // RTL
frame = nsBidiPresUtils::GetFrameToLeftOf(nullptr, firstFrameOnLine, numFramesOnLine);

View File

@ -49,6 +49,8 @@ public:
*
* @return true if the CSS direction property for the block is
* "rtl", otherwise false
*
*XXX after bug 924851 change this to return a UBiDiDirection
*/
virtual bool GetDirection() = 0;

View File

@ -870,17 +870,17 @@ nsFrameSelection::MoveCaret(uint32_t aKeycode,
nsPeekOffsetStruct pos(aAmount, eDirPrevious, offsetused, desiredX,
true, mLimiter != nullptr, true, aVisualMovement);
nsBidiLevel baseLevel = nsBidiPresUtils::GetFrameBaseLevel(frame);
nsBidiDirection paraDir = nsBidiPresUtils::ParagraphDirection(frame);
CaretAssociateHint tHint(mHint); //temporary variable so we dont set mHint until it is necessary
switch (aKeycode){
case nsIDOMKeyEvent::DOM_VK_RIGHT :
case nsIDOMKeyEvent::DOM_VK_RIGHT :
InvalidateDesiredX();
pos.mDirection = IS_LEVEL_RTL(baseLevel) ? eDirPrevious : eDirNext;
pos.mDirection = (paraDir == NSBIDI_RTL) ? eDirPrevious : eDirNext;
break;
case nsIDOMKeyEvent::DOM_VK_LEFT :
InvalidateDesiredX();
pos.mDirection = IS_LEVEL_RTL(baseLevel) ? eDirNext : eDirPrevious;
pos.mDirection = (paraDir == NSBIDI_RTL) ? eDirNext : eDirPrevious;
break;
case nsIDOMKeyEvent::DOM_VK_DELETE :
InvalidateDesiredX();
@ -5825,15 +5825,15 @@ Selection::Modify(const nsAString& aAlter, const nsAString& aDirection,
Collapse(focusNode, focusOffset);
}
// If the base level of the focused frame is odd, we may have to swap the
// direction of the keycode.
// If the paragraph direction of the focused frame is right-to-left,
// we may have to swap the direction of the keycode.
nsIFrame *frame;
int32_t offset;
rv = GetPrimaryFrameForFocusNode(&frame, &offset, visual);
if (NS_SUCCEEDED(rv) && frame) {
nsBidiLevel baseLevel = nsBidiPresUtils::GetFrameBaseLevel(frame);
nsBidiDirection paraDir = nsBidiPresUtils::ParagraphDirection(frame);
if (IS_LEVEL_RTL(baseLevel)) {
if (paraDir == NSBIDI_RTL) {
if (!visual && keycode == nsIDOMKeyEvent::DOM_VK_RIGHT) {
keycode = nsIDOMKeyEvent::DOM_VK_LEFT;
}