Backing out patches for bug 385270 (mostly --- due to other checkins in the meantime, the GetContent*() helper functions need to stay) to fix regressions. a=schrep

This commit is contained in:
roc+@cs.cmu.edu 2007-07-30 16:56:14 -07:00
parent e50a443cd2
commit 9009ef6bb7
2 changed files with 90 additions and 98 deletions

View File

@ -883,6 +883,16 @@ nsLineLayout::ReflowFrame(nsIFrame* aFrame,
nscoord ty = y - psd->mReflowState->mComputedBorderPadding.top;
mSpaceManager->Translate(tx, ty);
#ifdef IBMBIDI
PRInt32 start, end;
if (mPresContext->BidiEnabled()) {
if (aFrame->GetStateBits() & NS_FRAME_IS_BIDI) {
aFrame->GetOffsets(start, end);
}
}
#endif // IBMBIDI
nsIAtom* frameType = aFrame->GetType();
PRInt32 savedOptionalBreakOffset;
nsIContent* savedOptionalBreakContent =
@ -1076,6 +1086,24 @@ nsLineLayout::ReflowFrame(nsIFrame* aFrame,
printf(" status=%x\n", aReflowStatus);
#endif
if (aFrame->GetStateBits() & NS_FRAME_IS_BIDI) {
// Since aReflowStatus may change, check it at the end
if (NS_INLINE_IS_BREAK_BEFORE(aReflowStatus) ) {
aFrame->AdjustOffsetsForBidi(start, end);
}
else if (!NS_FRAME_IS_COMPLETE(aReflowStatus) ) {
PRInt32 newEnd;
aFrame->GetOffsets(start, newEnd);
if (newEnd != end) {
nsIFrame* nextInFlow = aFrame->GetNextInFlow();
if (nextInFlow) {
nextInFlow->GetOffsets(start, end);
nextInFlow->AdjustOffsetsForBidi(newEnd, end);
} // nextInFlow
} // newEnd != end
} // !NS_FRAME_IS_COMPLETE(aReflowStatus)
} // isBidiFrame
return rv;
}

View File

@ -138,10 +138,16 @@
// This bit is set on frames that trimmed trailing whitespace characters when
// calculating their width during reflow.
#define TEXT_TRIMMED_TRAILING_WHITESPACE 0x01000000
// Set when the frame's text may have a different style from its in-flow
// brethren (e.g. the frame is in first-letter or first-line), so text runs
// may need to be reconstructed when the frame's content offset/length changes.
// We set this on the frame that has in first-letter or first-line, but not
// in-flow siblings outside first-letter or first-line.
#define TEXT_RUN_LAYOUT_DEPENDENT 0x02000000
#define TEXT_REFLOW_FLAGS \
(TEXT_FIRST_LETTER|TEXT_START_OF_LINE|TEXT_END_OF_LINE|TEXT_HYPHEN_BREAK| \
TEXT_TRIMMED_TRAILING_WHITESPACE)
TEXT_TRIMMED_TRAILING_WHITESPACE|TEXT_RUN_LAYOUT_DEPENDENT)
// Cache bits for IsEmpty().
// Set this bit if the textframe is known to be only collapsible whitespace.
@ -498,15 +504,6 @@ public:
PRInt32 GetContentLength() const { return mContentLength; }
PRInt32 GetContentEnd() const { return mContentOffset + mContentLength; }
/**
* Fix up the content offsets for all next-in-flows so that they do not
* overlap this frame's content.
* @param aClearTextRuns if true, then any next-in-flows whose content
* offsets changed have their textruns cleared (as would be necessary
* if this frame could have a different style to those frames)
*/
void AdjustNextInFlowContentOffsetsForGrowth(PRBool aClearTextRuns);
// Compute the length of the content mapped by this frame
// and all its in-flow siblings. Basically this means starting at mContentOffset
// and going to the end of the text node or the next bidi continuation
@ -562,6 +559,8 @@ protected:
PRBool isRTLChars,
PRBool isOddLevel,
PRBool isBidiSystem);
void SetOffsets(PRInt32 start, PRInt32 end);
};
static void
@ -1339,9 +1338,12 @@ void BuildTextRunsScanner::ScanFrame(nsIFrame* aFrame)
!HasTerminalNewline(mLastFrame)) {
nsTextFrame* frame = static_cast<nsTextFrame*>(aFrame);
mappedFlow->mEndFrame = static_cast<nsTextFrame*>(frame->GetNextInFlow());
NS_ASSERTION(mappedFlow->mContentEndOffset <= frame->GetContentOffset(),
"frame offsets overlap!");
mappedFlow->mContentEndOffset = frame->GetContentEnd();
// Frames in the same flow can overlap at least temporarily
// (e.g. when first-line builds its textrun, we need to have it suck
// up all the in-flow content because we don't know how long the line
// is going to be).
mappedFlow->mContentEndOffset =
PR_MAX(mappedFlow->mContentEndOffset, frame->GetContentEnd());
AccumulateRunInfo(frame);
return;
}
@ -1563,8 +1565,12 @@ BuildTextRunsScanner::BuildTextRunForFrames(void* aTextBuffer)
PRInt32 contentLength = contentEnd - contentStart;
if (content == lastContent) {
NS_ASSERTION(endOfLastContent == contentStart,
"Gap in textframes mapping content, or overlap?!");
NS_ASSERTION(endOfLastContent >= contentStart,
"Gap in textframes mapping content?!");
// Text frames can overlap (see comment in ScanFrame below)
contentStart = PR_MAX(contentStart, endOfLastContent);
if (contentStart >= contentEnd)
continue;
userData->mMappedFlows[finalMappedFlowCount - 1].mContentLength += contentLength;
} else {
TextRunMappedFlow* newFlow = &userData->mMappedFlows[finalMappedFlowCount];
@ -3268,18 +3274,18 @@ nsContinuingTextFrame::Init(nsIContent* aContent,
// NOTE: bypassing nsTextFrame::Init!!!
nsresult rv = nsFrame::Init(aContent, aParent, aPrevInFlow);
nsIFrame* nextContinuation = aPrevInFlow->GetNextContinuation();
// Hook the frame into the flow
SetPrevInFlow(aPrevInFlow);
aPrevInFlow->SetNextInFlow(this);
nsTextFrame* prev = static_cast<nsTextFrame*>(aPrevInFlow);
nsTextFrame* nextContinuation = static_cast<nsTextFrame*>
(prev->GetNextContinuation());
SetPrevInFlow(prev);
prev->SetNextInFlow(this);
mTextRun = prev->GetTextRun();
mContentOffset = prev->GetContentEnd();
mContentLength = mContent->TextLength() - mContentOffset;
#ifdef IBMBIDI
if (prev->GetStateBits() & NS_FRAME_IS_BIDI) {
if (aPrevInFlow->GetStateBits() & NS_FRAME_IS_BIDI) {
PRInt32 start, end;
aPrevInFlow->GetOffsets(start, mContentOffset);
nsPropertyTable *propTable = PresContext()->PropertyTable();
propTable->SetProperty(this, nsGkAtoms::embeddingLevel,
propTable->GetProperty(aPrevInFlow, nsGkAtoms::embeddingLevel),
@ -3290,13 +3296,11 @@ nsContinuingTextFrame::Init(nsIContent* aContent,
propTable->SetProperty(this, nsGkAtoms::charType,
propTable->GetProperty(aPrevInFlow, nsGkAtoms::charType),
nsnull, nsnull);
if (nextContinuation) {
SetNextContinuation(nextContinuation);
nextContinuation->SetPrevContinuation(this);
NS_ASSERTION(mContentOffset <= nextContinuation->GetContentOffset(),
"Overlapping text ranges!");
mContentLength = nextContinuation->GetContentOffset() - mContentOffset;
nextContinuation->GetOffsets(start, end);
mContentLength = PR_MAX(1, start - mContentOffset);
}
mState |= NS_FRAME_IS_BIDI;
} // prev frame is bidi
@ -5158,26 +5162,6 @@ HasSoftHyphenBefore(const nsTextFragment* aFrag, gfxTextRun* aTextRun,
return PR_FALSE;
}
void
nsTextFrame::AdjustNextInFlowContentOffsetsForGrowth(PRBool aClearTextRuns)
{
PRInt32 end = GetContentEnd();
nsTextFrame* f = this;
NS_ASSERTION(!GetNextInFlow() ||
static_cast<nsTextFrame*>(GetNextInFlow())->GetContentOffset() <= GetContentEnd(),
"We shrunk, this should not be called");
while (PR_TRUE) {
f = static_cast<nsTextFrame*>(f->GetNextInFlow());
if (!f || f->GetContentOffset() >= end)
break;
f->mContentLength = PR_MAX(end, f->GetContentEnd()) - end;
f->mContentOffset = end;
if (aClearTextRuns) {
f->ClearTextRun();
}
}
}
NS_IMETHODIMP
nsTextFrame::Reflow(nsPresContext* aPresContext,
nsHTMLReflowMetrics& aMetrics,
@ -5201,16 +5185,25 @@ nsTextFrame::Reflow(nsPresContext* aPresContext,
// can change whether the frame maps whitespace-only text or not.
RemoveStateBits(TEXT_REFLOW_FLAGS | TEXT_WHITESPACE_FLAGS);
NS_ASSERTION(!GetPrevInFlow() ||
static_cast<nsTextFrame*>(GetPrevInFlow())->GetContentEnd() == mContentOffset,
"Discontinuous content offsets!");
nsTextFrame* prevInFlow = static_cast<nsTextFrame*>(GetPrevInFlow());
if (prevInFlow) {
// Our mContentOffset may be out of date due to our prev-in-flow growing or
// shrinking. Update it.
mContentOffset = prevInFlow->GetContentEnd();
}
// Temporarily map all possible content while we construct our new textrun.
// so that when doing reflow our styles prevail over any part of the
// textrun we look at. Note that next-in-flows may be mapping the same
// content; gfxTextRun construction logic will ensure that we take priority.
PRInt32 maxContentLength = GetInFlowContentLength();
mContentLength = maxContentLength;
// XXX If there's no line layout, we shouldn't even have created this
// frame. This may happen if, for example, this is text inside a table
// but not inside a cell. For now, just don't reflow. We also don't need to
// reflow if there is no content.
if (!aReflowState.mLineLayout || !maxContentLength) {
if (!aReflowState.mLineLayout || !mContentLength) {
ClearMetrics(aMetrics);
aStatus = NS_FRAME_COMPLETE;
return NS_OK;
@ -5249,15 +5242,11 @@ nsTextFrame::Reflow(nsPresContext* aPresContext,
PRBool layoutDependentTextRun =
lineLayout.GetFirstLetterStyleOK() || lineLayout.GetInFirstLine();
if (layoutDependentTextRun) {
AddStateBits(TEXT_RUN_LAYOUT_DEPENDENT);
}
if (layoutDependentTextRun ||
(prevInFlow && (prevInFlow->GetStateBits() & TEXT_RUN_LAYOUT_DEPENDENT))) {
ClearTextRun();
// Temporarily map all possible content while we construct our new textrun.
// so that when doing reflow our styles prevail over any part of the
// textrun we look at.
mContentLength = maxContentLength;
// The following loop is going to traverse all in-flow frames, which could
// be kinda slow, but we're going to have to rebuild all their text runs
// anyway so this shouldn't be any worse
AdjustNextInFlowContentOffsetsForGrowth(PR_TRUE);
}
PRUint32 flowEndInTextRun;
@ -5276,7 +5265,7 @@ nsTextFrame::Reflow(nsPresContext* aPresContext,
// DOM offsets of the text range we need to measure, after trimming
// whitespace, restricting to first-letter, and restricting preformatted text
// to nearest newline
PRInt32 length = maxContentLength;
PRInt32 length = mContentLength;
PRInt32 offset = mContentOffset;
// Restrict preformatted text to the nearest newline
@ -5430,27 +5419,6 @@ nsTextFrame::Reflow(nsPresContext* aPresContext,
AddStateBits(TEXT_TRIMMED_TRAILING_WHITESPACE);
}
mContentLength = offset + charsFit - mContentOffset;
// Now fix up content offsets/lengths for in-flows
nsTextFrame* f = static_cast<nsTextFrame*>(GetNextInFlow());
if (f) {
if (f->GetContentOffset() > GetContentEnd()) {
// We must have shrunk. Add the leftover text to the start of f.
f->mContentLength = f->GetContentEnd() - GetContentEnd();
f->mContentOffset = GetContentEnd();
if (layoutDependentTextRun) {
// f's textrun may need to change since the text style may be
// different.
f->ClearTextRun();
}
} else if (f->GetContentOffset() < GetContentEnd()) {
// We must have grown. Remove the text from f and possibly its
// continuations.
NS_ASSERTION(!layoutDependentTextRun,
"We should have grown up above and be shrinking here!");
AdjustNextInFlowContentOffsetsForGrowth(layoutDependentTextRun);
}
}
/////////////////////////////////////////////////////////////////////
// Compute output metrics
@ -5619,9 +5587,9 @@ nsTextFrame::TrimTrailingWhiteSpace(nsPresContext* aPresContext,
if (GetStateBits() & TEXT_TRIMMED_TRAILING_WHITESPACE) {
aLastCharIsJustifiable = PR_TRUE;
} else if (trimmed.mStart + trimmed.mLength < GetContentEnd()) {
} else if (trimmed.mStart + trimmed.mLength < mContentOffset + mContentLength) {
gfxSkipCharsIterator end = iter;
PRUint32 endOffset = end.ConvertOriginalToSkipped(GetContentEnd());
PRUint32 endOffset = end.ConvertOriginalToSkipped(mContentOffset + mContentLength);
if (trimmedEnd < endOffset) {
// We can't be dealing with tabs here ... they wouldn't be trimmed. So it's
// OK to pass null for the line container.
@ -5896,24 +5864,20 @@ void
nsTextFrame::AdjustOffsetsForBidi(PRInt32 aStart, PRInt32 aEnd)
{
AddStateBits(NS_FRAME_IS_BIDI);
SetOffsets(aStart, aEnd);
/*
* After Bidi resolution we may need to reassign text runs.
* This is called during bidi resolution from the block container, so we
* shouldn't be holding a local reference to a textrun anywhere.
*/
ClearTextRun();
}
void
nsTextFrame::SetOffsets(PRInt32 aStart, PRInt32 aEnd)
{
mContentOffset = aStart;
mContentLength = aEnd - aStart;
nsTextFrame* f = this;
// We were just assigned all the content for this in-flow run, so unmap all
// next-in-flows
while (PR_TRUE) {
/*
* After Bidi resolution we may need to reassign text runs.
* This is called during bidi resolution from the block container, so we
* shouldn't be holding a local reference to a textrun anywhere.
*/
f->ClearTextRun();
f = static_cast<nsTextFrame*>(f->GetNextInFlow());
if (!f)
break;
f->mContentOffset = aEnd;
f->mContentLength = 0;
}
}
/**