зеркало из https://github.com/mozilla/gecko-dev.git
Don't bidi-split line frames. bug=364839, r+sr=bzbarsky.
This commit is contained in:
Родитель
c5a06bdb6d
Коммит
26b820a880
|
@ -101,6 +101,15 @@ nsBidiPresUtils::IsSuccessful() const
|
|||
|
||||
/* Some helper methods for Resolve() */
|
||||
|
||||
// Should this frame be split between text runs?
|
||||
PRBool
|
||||
IsBidiSplittable(nsIFrame* aFrame) {
|
||||
nsIAtom* frameType = aFrame->GetType();
|
||||
// Bidi inline containers should be split, unless they're line frames.
|
||||
return aFrame->IsFrameOfType(nsIFrame::eBidiInlineContainer)
|
||||
&& frameType != nsGkAtoms::lineFrame;
|
||||
}
|
||||
|
||||
static nsresult
|
||||
SplitInlineAncestors(nsPresContext* aPresContext,
|
||||
nsIFrame* aFrame)
|
||||
|
@ -111,7 +120,7 @@ SplitInlineAncestors(nsPresContext* aPresContext,
|
|||
nsIFrame* newFrame = aFrame->GetNextSibling();
|
||||
nsIFrame* newParent;
|
||||
|
||||
while (parent->IsFrameOfType(nsIFrame::eBidiInlineContainer)) {
|
||||
while (IsBidiSplittable(parent)) {
|
||||
nsIFrame* grandparent = parent->GetParent();
|
||||
NS_ASSERTION(grandparent, "Couldn't get parent's parent in nsBidiPresUtils::SplitInlineAncestors");
|
||||
|
||||
|
@ -447,12 +456,12 @@ nsBidiPresUtils::Resolve(nsPresContext* aPresContext,
|
|||
nsIFrame* child = frame;
|
||||
nsIFrame* parent = frame->GetParent();
|
||||
while (parent &&
|
||||
parent->IsFrameOfType(nsIFrame::eBidiInlineContainer) &&
|
||||
IsBidiSplittable(parent) &&
|
||||
!child->GetNextSibling()) {
|
||||
child = parent;
|
||||
parent = child->GetParent();
|
||||
}
|
||||
if (parent && parent->IsFrameOfType(nsIFrame::eBidiInlineContainer))
|
||||
if (parent && IsBidiSplittable(parent))
|
||||
SplitInlineAncestors(aPresContext, child);
|
||||
}
|
||||
} // for
|
||||
|
@ -461,7 +470,6 @@ nsBidiPresUtils::Resolve(nsPresContext* aPresContext,
|
|||
|
||||
// Should this frame be treated as a leaf (e.g. when building mLogicalArray)?
|
||||
PRBool IsBidiLeaf(nsIFrame* aFrame) {
|
||||
nsIAtom* frameType = aFrame->GetType();
|
||||
nsIFrame* kid = aFrame->GetFirstChild(nsnull);
|
||||
// Need the IsBlockLevel() check because nsFirstLetterFrame is
|
||||
// always of type eBidiInlineContainer, even if it's floating.
|
||||
|
@ -608,6 +616,14 @@ nsBidiPresUtils::ReorderFrames(nsPresContext* aPresContext,
|
|||
nsIFrame* aFirstFrameOnLine,
|
||||
PRInt32 aNumFramesOnLine)
|
||||
{
|
||||
// If this line consists of a line frame, reorder the line frame's children.
|
||||
if (aFirstFrameOnLine->GetType() == nsGkAtoms::lineFrame) {
|
||||
aFirstFrameOnLine = aFirstFrameOnLine->GetFirstChild(nsnull);
|
||||
// All children of the line frame are on the first line. Setting aNumFramesOnLine
|
||||
// to -1 makes InitLogicalArrayFromLine look at all of them.
|
||||
aNumFramesOnLine = -1;
|
||||
}
|
||||
|
||||
InitLogicalArrayFromLine(aFirstFrameOnLine, aNumFramesOnLine);
|
||||
|
||||
PRBool isReordered;
|
||||
|
|
|
@ -442,21 +442,32 @@ nsFrameList::GetPrevVisualFor(nsIFrame* aFrame) const
|
|||
if (!parent)
|
||||
return aFrame ? GetPrevSiblingFor(aFrame) : LastChild();
|
||||
|
||||
nsBidiLevel baseLevel = nsBidiPresUtils::GetFrameBaseLevel(mFirstChild);
|
||||
|
||||
nsBidiLevel baseLevel = nsBidiPresUtils::GetFrameBaseLevel(mFirstChild);
|
||||
nsBidiPresUtils* bidiUtils = mFirstChild->GetPresContext()->GetBidiUtils();
|
||||
|
||||
nsresult result = parent->QueryInterface(NS_GET_IID(nsILineIterator), (void**)&iter);
|
||||
if (NS_FAILED(result) || !iter) {
|
||||
// If the parent is not a block frame, just get the next or prev sibling, depending on block and frame direction.
|
||||
nsBidiLevel frameEmbeddingLevel = nsBidiPresUtils::GetFrameEmbeddingLevel(mFirstChild);
|
||||
if ((frameEmbeddingLevel & 1) == (baseLevel & 1)) {
|
||||
return aFrame ? GetPrevSiblingFor(aFrame) : LastChild();
|
||||
// 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) {
|
||||
return bidiUtils->GetFrameToLeftOf(aFrame, mFirstChild, -1);
|
||||
} else { // RTL
|
||||
return bidiUtils->GetFrameToRightOf(aFrame, mFirstChild, -1);
|
||||
}
|
||||
} else {
|
||||
return aFrame ? aFrame->GetNextSibling() : mFirstChild;
|
||||
}
|
||||
// Just get the next or prev sibling, depending on block and frame direction.
|
||||
nsBidiLevel frameEmbeddingLevel = nsBidiPresUtils::GetFrameEmbeddingLevel(mFirstChild);
|
||||
if ((frameEmbeddingLevel & 1) == (baseLevel & 1)) {
|
||||
return aFrame ? GetPrevSiblingFor(aFrame) : LastChild();
|
||||
} else {
|
||||
return aFrame ? aFrame->GetNextSibling() : mFirstChild;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Otherwise use the LineIterator to find the previous visual sibling on this line,
|
||||
// or the last one on the previous line.
|
||||
// Parent is a block frame, so use the LineIterator to find the previous visual
|
||||
// sibling on this line, or the last one on the previous line.
|
||||
|
||||
PRInt32 thisLine;
|
||||
if (aFrame) {
|
||||
|
@ -466,9 +477,7 @@ nsFrameList::GetPrevVisualFor(nsIFrame* aFrame) const
|
|||
} else {
|
||||
iter->GetNumLines(&thisLine);
|
||||
}
|
||||
|
||||
nsBidiPresUtils* bidiUtils = mFirstChild->GetPresContext()->GetBidiUtils();
|
||||
|
||||
|
||||
nsIFrame* frame = nsnull;
|
||||
nsIFrame* firstFrameOnLine;
|
||||
PRInt32 numFramesOnLine;
|
||||
|
@ -511,20 +520,31 @@ nsFrameList::GetNextVisualFor(nsIFrame* aFrame) const
|
|||
return aFrame ? GetPrevSiblingFor(aFrame) : mFirstChild;
|
||||
|
||||
nsBidiLevel baseLevel = nsBidiPresUtils::GetFrameBaseLevel(mFirstChild);
|
||||
nsBidiPresUtils* bidiUtils = mFirstChild->GetPresContext()->GetBidiUtils();
|
||||
|
||||
nsresult result = parent->QueryInterface(NS_GET_IID(nsILineIterator), (void**)&iter);
|
||||
if (NS_FAILED(result) || !iter) {
|
||||
// If the parent is not a block frame, just get the next or prev sibling, depending on block and frame direction.
|
||||
nsBidiLevel frameEmbeddingLevel = nsBidiPresUtils::GetFrameEmbeddingLevel(mFirstChild);
|
||||
if ((frameEmbeddingLevel & 1) == (baseLevel & 1)) {
|
||||
return aFrame ? aFrame->GetNextSibling() : mFirstChild;
|
||||
if (NS_FAILED(result) || !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) {
|
||||
return bidiUtils->GetFrameToRightOf(aFrame, mFirstChild, -1);
|
||||
} else { // RTL
|
||||
return bidiUtils->GetFrameToLeftOf(aFrame, mFirstChild, -1);
|
||||
}
|
||||
} else {
|
||||
return aFrame ? GetPrevSiblingFor(aFrame) : LastChild();
|
||||
}
|
||||
// Just get the next or prev sibling, depending on block and frame direction.
|
||||
nsBidiLevel frameEmbeddingLevel = nsBidiPresUtils::GetFrameEmbeddingLevel(mFirstChild);
|
||||
if ((frameEmbeddingLevel & 1) == (baseLevel & 1)) {
|
||||
return aFrame ? aFrame->GetNextSibling() : mFirstChild;
|
||||
} else {
|
||||
return aFrame ? GetPrevSiblingFor(aFrame) : LastChild();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Otherwise use the LineIterator to find the next visual sibling on this line,
|
||||
// or the first one on the next line.
|
||||
// Parent is a block frame, so use the LineIterator to find the next visual
|
||||
// sibling on this line, or the first one on the next line.
|
||||
|
||||
PRInt32 thisLine;
|
||||
if (aFrame) {
|
||||
|
@ -534,9 +554,7 @@ nsFrameList::GetNextVisualFor(nsIFrame* aFrame) const
|
|||
} else {
|
||||
thisLine = -1;
|
||||
}
|
||||
|
||||
nsBidiPresUtils* bidiUtils = mFirstChild->GetPresContext()->GetBidiUtils();
|
||||
|
||||
|
||||
nsIFrame* frame = nsnull;
|
||||
nsIFrame* firstFrameOnLine;
|
||||
PRInt32 numFramesOnLine;
|
||||
|
|
Загрузка…
Ссылка в новой задаче