Don't split frames in bidi resolution that have the same resolved directionality but different character types. Bug 399850, r=ehsan, roc

This commit is contained in:
Simon Montagu 2010-05-10 23:14:05 -07:00
parent 65c6e97f09
commit 85a1e8061a
3 changed files with 11 additions and 37 deletions

View File

@ -300,14 +300,13 @@ AdvanceLineIteratorToFrame(nsIFrame* aFrame,
*
* Finally, walk these runs in logical order using nsBidi::GetLogicalRun() and
* correlate them with the frames indexed in mLogicalFrames, setting the
* baseLevel, embeddingLevel, and charType properties according to the results
* returned by the Bidi engine and CalculateCharType().
* baseLevel and embeddingLevel properties according to the results returned
* by the Bidi engine.
*
* The rendering layer requires each text frame to contain text in only one
* direction and of only one character type, so we may need to call
* EnsureBidiContinuation() to split frames. We may also need to call
* RemoveBidiContinuation() to convert frames created by
* EnsureBidiContinuation() in previous reflows into fluid continuations.
* direction, so we may need to call EnsureBidiContinuation() to split frames.
* We may also need to call RemoveBidiContinuation() to convert frames created
* by EnsureBidiContinuation() in previous reflows into fluid continuations.
*/
nsresult
nsBidiPresUtils::Resolve(nsBlockFrame* aBlockFrame)
@ -383,8 +382,6 @@ nsBidiPresUtils::Resolve(nsBlockFrame* aBlockFrame)
PRInt32 frameIndex = -1; // index to the frames in mLogicalFrames
PRInt32 frameCount = mLogicalFrames.Length();
PRInt32 contentOffset = 0; // offset of current frame in its content node
PRUint8 charType;
PRUint8 prevType = eCharType_LeftToRight;
PRBool isTextFrame = PR_FALSE;
nsIFrame* frame = nsnull;
nsIContent* content = nsnull;
@ -494,14 +491,6 @@ nsBidiPresUtils::Resolve(nsBlockFrame* aBlockFrame)
propTable->Set(frame, nsIFrame::BaseLevelProperty(),
NS_INT32_TO_PTR(paraLevel));
if (isTextFrame) {
PRInt32 typeLimit = NS_MIN(logicalLimit, lineOffset + fragmentLength);
CalculateCharType(lineOffset, typeLimit, logicalLimit, runLength,
runCount, charType, prevType);
// IBMBIDI - Egypt - Start
propTable->Set(frame, nsIFrame::CharTypeProperty(),
NS_INT32_TO_PTR(charType));
// IBMBIDI - Egypt - End
if ( (runLength > 0) && (runLength < fragmentLength) ) {
/*
* The text in this frame continues beyond the end of this directional run.
@ -1199,11 +1188,9 @@ nsBidiPresUtils::RemoveBidiContinuation(nsIFrame* aFrame,
{
FrameProperties props = aFrame->Properties();
nsBidiLevel embeddingLevel =
(nsCharType)NS_PTR_TO_INT32(props.Get(nsIFrame::EmbeddingLevelProperty()));
(nsBidiLevel)NS_PTR_TO_INT32(props.Get(nsIFrame::EmbeddingLevelProperty()));
nsBidiLevel baseLevel =
(nsCharType)NS_PTR_TO_INT32(props.Get(nsIFrame::BaseLevelProperty()));
nsCharType charType =
(nsCharType)NS_PTR_TO_INT32(props.Get(nsIFrame::CharTypeProperty()));
(nsBidiLevel)NS_PTR_TO_INT32(props.Get(nsIFrame::BaseLevelProperty()));
for (PRInt32 index = aFirstIndex + 1; index <= aLastIndex; index++) {
nsIFrame* frame = mLogicalFrames[index];
@ -1219,8 +1206,6 @@ nsBidiPresUtils::RemoveBidiContinuation(nsIFrame* aFrame,
NS_INT32_TO_PTR(embeddingLevel));
frameProps.Set(nsIFrame::BaseLevelProperty(),
NS_INT32_TO_PTR(baseLevel));
frameProps.Set(nsIFrame::CharTypeProperty(),
NS_INT32_TO_PTR(charType));
frame->AddStateBits(NS_FRAME_IS_BIDI);
while (frame) {
nsIFrame* prev = frame->GetPrevContinuation();

View File

@ -2171,7 +2171,6 @@ public:
NS_DECLARE_FRAME_PROPERTY(BaseLevelProperty, nsnull)
NS_DECLARE_FRAME_PROPERTY(EmbeddingLevelProperty, nsnull)
NS_DECLARE_FRAME_PROPERTY(CharTypeProperty, nsnull)
#define NS_GET_BASE_LEVEL(frame) \
NS_PTR_TO_INT32(frame->Properties().Get(nsIFrame::BaseLevelProperty()))

View File

@ -1333,16 +1333,9 @@ BuildTextRunsScanner::ContinueTextRunAcrossFrames(nsTextFrame* aFrame1, nsTextFr
if (textStyle1->NewlineIsSignificant() && HasTerminalNewline(aFrame1))
return PR_FALSE;
if (aFrame1->GetContent() == aFrame2->GetContent() &&
aFrame1->GetNextInFlow() != aFrame2) {
// aFrame2 must be a non-fluid continuation of aFrame1. This can happen
// sometimes when the unicode-bidi property is used; the bidi resolver
// breaks text into different frames even though the text has the same
// direction. We can't allow these two frames to share the same textrun
// because that would violate our invariant that two flows in the same
// textrun have different content elements.
return PR_FALSE;
}
NS_ASSERTION(aFrame1->GetContent() != aFrame2->GetContent() ||
aFrame1->GetNextInFlow() == aFrame2,
"can't continue text run across non-fluid continuations");
nsStyleContext* sc2 = aFrame2->GetStyleContext();
if (sc1 == sc2)
@ -3531,10 +3524,8 @@ nsContinuingTextFrame::Init(nsIContent* aContent,
// advantage of the propTable's cache and simplify the assertion below
void* embeddingLevel = propTable->Get(aPrevInFlow, EmbeddingLevelProperty());
void* baseLevel = propTable->Get(aPrevInFlow, BaseLevelProperty());
void* charType = propTable->Get(aPrevInFlow, CharTypeProperty());
propTable->Set(this, EmbeddingLevelProperty(), embeddingLevel);
propTable->Set(this, BaseLevelProperty(), baseLevel);
propTable->Set(this, CharTypeProperty(), charType);
if (nextContinuation) {
SetNextContinuation(nextContinuation);
@ -3544,8 +3535,7 @@ nsContinuingTextFrame::Init(nsIContent* aContent,
nextContinuation->GetContentOffset() < mContentOffset) {
NS_ASSERTION(
embeddingLevel == propTable->Get(nextContinuation, EmbeddingLevelProperty()) &&
baseLevel == propTable->Get(nextContinuation, BaseLevelProperty()) &&
charType == propTable->Get(nextContinuation, CharTypeProperty()),
baseLevel == propTable->Get(nextContinuation, BaseLevelProperty()),
"stealing text from different type of BIDI continuation");
nextContinuation->mContentOffset = mContentOffset;
nextContinuation = static_cast<nsTextFrame*>(nextContinuation->GetNextContinuation());