Don't bidi-split line frames. bug=364839, r+sr=bzbarsky.

This commit is contained in:
uriber%gmail.com 2007-01-13 18:20:28 +00:00
Родитель c5a06bdb6d
Коммит 26b820a880
2 изменённых файлов: 63 добавлений и 29 удалений

Просмотреть файл

@ -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;