Fixed various incremental reflow bugs (1764,12890,1910,2222) and list bullet painting bug (10675,13599)

This commit is contained in:
kipp%netscape.com 1999-09-15 00:28:10 +00:00
Родитель 71877ee89f
Коммит 6488f7b26e
12 изменённых файлов: 2714 добавлений и 1952 удалений

Разница между файлами не показана из-за своего большого размера Загрузить разницу

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

@ -115,9 +115,6 @@ public:
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus);
NS_IMETHOD MoveInSpaceManager(nsIPresContext* aPresContext,
nsISpaceManager* aSpaceManager,
nscoord aDeltaX, nscoord aDeltaY);
NS_IMETHOD AttributeChanged(nsIPresContext* aPresContext,
nsIContent* aChild,
@ -144,6 +141,9 @@ public:
nsIFrame* GetTopBlockChild();
nsresult UpdateSpaceManager(nsIPresContext* aPresContext,
nsISpaceManager* aSpaceManager);
protected:
nsBlockFrame();
virtual ~nsBlockFrame();
@ -166,10 +166,6 @@ protected:
nsISpaceManager* aSpaceManager,
nsLineBox* aLine, nscoord aDY);
void SlideFloaters(nsIPresContext* aPresContext,
nsISpaceManager* aSpaceManager,
nsLineBox* aLine, nscoord aDY);
PRBool DrainOverflowLines();
virtual PRIntn GetSkipSides() const;
@ -228,10 +224,6 @@ protected:
PRBool* aKeepReflowGoing,
PRBool aDamageDirtyArea = PR_FALSE);
virtual void DidReflowLine(nsBlockReflowState& aState,
nsLineBox* aLine,
PRBool aKeepReflowGoing);
nsresult PlaceLine(nsBlockReflowState& aState,
nsLineLayout& aLineLayout,
nsLineBox* aLine,
@ -249,8 +241,6 @@ protected:
// XXX where to go
PRBool ShouldJustifyLine(nsBlockReflowState& aState, nsLineBox* aLine);
void FindFloaters(nsLineBox* aLine);
void DeleteLine(nsBlockReflowState& aState, nsLineBox* aLine);
//----------------------------------------
@ -339,6 +329,7 @@ protected:
void PropogateReflowDamage(nsBlockReflowState& aState,
nsLineBox* aLine,
const nsRect& aOldCombinedArea,
nscoord aDeltaY);
nsresult ComputeTextRuns(nsIPresContext* aPresContext);

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Разница между файлами не показана из-за своего большого размера Загрузить разницу

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

@ -27,7 +27,6 @@ nsLineBox::nsLineBox(nsIFrame* aFrame, PRInt32 aCount, PRUint16 flags)
mFirstChild = aFrame;
mChildCount = aCount;
mState = LINE_IS_DIRTY | flags;
mFloaters = nsnull;
mNext = nsnull;
mBounds.SetRect(0,0,0,0);
mCombinedArea.SetRect(0,0,0,0);
@ -39,19 +38,16 @@ nsLineBox::nsLineBox(nsIFrame* aFrame, PRInt32 aCount, PRUint16 flags)
nsLineBox::~nsLineBox()
{
if (nsnull != mFloaters) {
delete mFloaters;
}
}
static void
ListFloaters(FILE* out, PRInt32 aIndent, nsVoidArray* aFloaters)
ListFloaters(FILE* out, PRInt32 aIndent, const nsFloaterCacheList& aFloaters)
{
nsAutoString frameName;
PRInt32 j, i, n = aFloaters->Count();
for (i = 0; i < n; i++) {
for (j = aIndent; --j >= 0; ) fputs(" ", out);
nsPlaceholderFrame* ph = (nsPlaceholderFrame*) aFloaters->ElementAt(i);
nsFloaterCache* fc = aFloaters.Head();
while (fc) {
nsFrame::IndentBy(out, aIndent);
nsPlaceholderFrame* ph = fc->mPlaceholder;
if (nsnull != ph) {
fprintf(out, "placeholder@%p ", ph);
nsIFrame* frame = ph->GetOutOfFlowFrame();
@ -59,8 +55,13 @@ ListFloaters(FILE* out, PRInt32 aIndent, nsVoidArray* aFloaters)
frame->GetFrameName(frameName);
fputs(frameName, out);
}
fprintf(out, " %s region={%d,%d,%d,%d}",
fc->mIsCurrentLineFloater ? "cl" : "bcl",
fc->mRegion.x, fc->mRegion.y,
fc->mRegion.width, fc->mRegion.height);
fprintf(out, "\n");
}
fc = fc->Next();
}
}
@ -105,7 +106,7 @@ nsLineBox::List(FILE* out, PRInt32 aIndent) const
}
for (i = aIndent; --i >= 0; ) fputs(" ", out);
if (nsnull != mFloaters) {
if (mFloaters.NotEmpty()) {
fputs("> floaters <\n", out);
ListFloaters(out, aIndent + 1, mFloaters);
for (i = aIndent; --i >= 0; ) fputs(" ", out);
@ -463,3 +464,128 @@ nsLineIterator::FindFrameAt(PRInt32 aLineNumber,
*aFrameFound = frame;
return NS_OK;
}
//----------------------------------------------------------------------
nsFloaterCacheList::~nsFloaterCacheList()
{
nsFloaterCache* floater = mHead;
while (floater) {
nsFloaterCache* next = floater->mNext;
delete floater;
floater = next;
}
}
nsFloaterCache*
nsFloaterCacheList::Tail() const
{
nsFloaterCache* fc = mHead;
while (fc) {
if (!fc->mNext) {
break;
}
fc = fc->mNext;
}
return fc;
}
void
nsFloaterCacheList::Append(nsFloaterCacheFreeList& aList)
{
nsFloaterCache* tail = Tail();
if (tail) {
tail->mNext = aList.mHead;
}
else {
mHead = aList.mHead;
}
aList.mHead = nsnull;
aList.mTail = nsnull;
}
nsFloaterCache*
nsFloaterCacheList::Find(nsIFrame* aOutOfFlowFrame)
{
nsFloaterCache* fc = mHead;
while (fc) {
if (fc->mPlaceholder->GetOutOfFlowFrame() == aOutOfFlowFrame) {
break;
}
fc = fc->Next();
}
return fc;
}
void
nsFloaterCacheList::Remove(nsFloaterCache* aElement)
{
nsFloaterCache** fcp = &mHead;
nsFloaterCache* fc;
while (nsnull != (fc = *fcp)) {
if (fc == aElement) {
*fcp = fc->mNext;
break;
}
fcp = &fc->mNext;
}
}
//----------------------------------------------------------------------
void
nsFloaterCacheFreeList::Append(nsFloaterCacheList& aList)
{
if (mTail) {
mTail->mNext = aList.mHead;
}
else {
mHead = aList.mHead;
}
mTail = aList.Tail();
aList.mHead = nsnull;
}
nsFloaterCache*
nsFloaterCacheFreeList::Alloc()
{
nsFloaterCache* fc = mHead;
if (mHead) {
if (mHead == mTail) {
mHead = mTail = nsnull;
}
else {
mHead = fc->mNext;
}
fc->mNext = nsnull;
}
else {
fc = new nsFloaterCache();
}
return fc;
}
void
nsFloaterCacheFreeList::Append(nsFloaterCache* aFloater)
{
aFloater->mNext = nsnull;
if (mTail) {
mTail->mNext = aFloater;
mTail = aFloater;
}
else {
mHead = mTail = aFloater;
}
}
//----------------------------------------------------------------------
nsFloaterCache::nsFloaterCache()
: mPlaceholder(nsnull),
mIsCurrentLineFloater(PR_TRUE),
mMargins(0, 0, 0, 0),
mOffsets(0, 0, 0, 0),
mCombinedArea(0, 0, 0, 0),
mNext(nsnull)
{
}

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

@ -24,16 +24,117 @@
#include "nsILineIterator.h"
// bits in nsLineBox.mState
#define LINE_IS_DIRTY 0x1
#define LINE_IS_BLOCK 0x2
#define LINE_IS_DIRTY 0x1
#define LINE_IS_BLOCK 0x2
#define LINE_IS_IMPACTED_BY_FLOATER 0x4
#ifdef BLOCK_DOES_FIRST_LINE
#define LINE_IS_FIRST_LINE 0x4
#define LINE_IS_FIRST_LINE 0x8
#endif
#define LINE_WAS_DIRTY 0x8
#define LINE_WAS_DIRTY 0x10
class nsISpaceManager;
class nsLineBox;
//----------------------------------------------------------------------
class nsFloaterCache;
class nsFloaterCacheList;
class nsFloaterCacheFreeList;
// State cached after reflowing a floater. This state is used during
// incremental reflow when we avoid reflowing a floater.
class nsFloaterCache {
public:
nsFloaterCache();
~nsFloaterCache() { }
nsFloaterCache* Next() const { return mNext; }
nsPlaceholderFrame* mPlaceholder; // nsPlaceholderFrame
// This will be true if the floater was placed on the current line
// instead of below the current line.
PRBool mIsCurrentLineFloater;
nsMargin mMargins; // computed margins
nsMargin mOffsets; // computed offsets (relative pos)
// Region in the spacemanager impacted by this floater; the
// coordinates are relative to the containing block frame. The
// region includes the margins around the floater, but doesn't
// include the relative offsets.
nsRect mRegion;
// Combined area for the floater. This will not include the margins
// for the floater. Like mRegion, the coordinates are relative to
// the containing block frame.
nsRect mCombinedArea;
protected:
nsFloaterCache* mNext;
friend class nsFloaterCacheList;
friend class nsFloaterCacheFreeList;
};
//----------------------------------------
class nsFloaterCacheList {
public:
nsFloaterCacheList() : mHead(nsnull) { }
~nsFloaterCacheList();
PRBool IsEmpty() const {
return nsnull == mHead;
}
PRBool NotEmpty() const {
return nsnull != mHead;
}
nsFloaterCache* Head() const {
return mHead;
}
nsFloaterCache* Tail() const;
nsFloaterCache* Find(nsIFrame* aOutOfFlowFrame);
void Remove(nsFloaterCache* aElement);
void Append(nsFloaterCacheFreeList& aList);
protected:
nsFloaterCache* mHead;
friend class nsFloaterCacheFreeList;
};
//---------------------------------------
class nsFloaterCacheFreeList : public nsFloaterCacheList {
public:
nsFloaterCacheFreeList() : mTail(nsnull) { }
~nsFloaterCacheFreeList() { }
// Steal away aList's nsFloaterCache objects and put them on this
// free-list.
void Append(nsFloaterCacheList& aList);
void Append(nsFloaterCache* aFloaterCache);
// Allocate a new nsFloaterCache object
nsFloaterCache* Alloc();
protected:
nsFloaterCache* mTail;
friend class nsFloaterCacheList;
};
//----------------------------------------------------------------------
/**
* The nsLineBox class represents a horizontal line of frames. It contains
* enough state to support incremental reflow of the frames, event handling
@ -92,6 +193,19 @@ public:
}
}
void SetLineIsImpactedByFloater(PRBool aValue) {
if (aValue) {
mState |= LINE_IS_IMPACTED_BY_FLOATER;
}
else {
mState &= ~LINE_IS_IMPACTED_BY_FLOATER;
}
}
PRBool IsImpactedByFloater() const {
return 0 != (LINE_IS_IMPACTED_BY_FLOATER & mState);
}
#ifdef BLOCK_DOES_FIRST_LINE
PRBool IsFirstLine() const {
return 0 != (LINE_IS_FIRST_LINE & mState);
@ -150,7 +264,7 @@ public:
nsRect mBounds;
nsRect mCombinedArea;
nscoord mCarriedOutBottomMargin;/* XXX switch to 16 bits */
nsVoidArray* mFloaters;
nsFloaterCacheList mFloaters;
nsLineBox* mNext;
nscoord mMaxElementWidth; // width part of max-element-size
};

Разница между файлами не показана из-за своего большого размера Загрузить разницу

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

@ -115,9 +115,6 @@ public:
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus);
NS_IMETHOD MoveInSpaceManager(nsIPresContext* aPresContext,
nsISpaceManager* aSpaceManager,
nscoord aDeltaX, nscoord aDeltaY);
NS_IMETHOD AttributeChanged(nsIPresContext* aPresContext,
nsIContent* aChild,
@ -144,6 +141,9 @@ public:
nsIFrame* GetTopBlockChild();
nsresult UpdateSpaceManager(nsIPresContext* aPresContext,
nsISpaceManager* aSpaceManager);
protected:
nsBlockFrame();
virtual ~nsBlockFrame();
@ -166,10 +166,6 @@ protected:
nsISpaceManager* aSpaceManager,
nsLineBox* aLine, nscoord aDY);
void SlideFloaters(nsIPresContext* aPresContext,
nsISpaceManager* aSpaceManager,
nsLineBox* aLine, nscoord aDY);
PRBool DrainOverflowLines();
virtual PRIntn GetSkipSides() const;
@ -228,10 +224,6 @@ protected:
PRBool* aKeepReflowGoing,
PRBool aDamageDirtyArea = PR_FALSE);
virtual void DidReflowLine(nsBlockReflowState& aState,
nsLineBox* aLine,
PRBool aKeepReflowGoing);
nsresult PlaceLine(nsBlockReflowState& aState,
nsLineLayout& aLineLayout,
nsLineBox* aLine,
@ -249,8 +241,6 @@ protected:
// XXX where to go
PRBool ShouldJustifyLine(nsBlockReflowState& aState, nsLineBox* aLine);
void FindFloaters(nsLineBox* aLine);
void DeleteLine(nsBlockReflowState& aState, nsLineBox* aLine);
//----------------------------------------
@ -339,6 +329,7 @@ protected:
void PropogateReflowDamage(nsBlockReflowState& aState,
nsLineBox* aLine,
const nsRect& aOldCombinedArea,
nscoord aDeltaY);
nsresult ComputeTextRuns(nsIPresContext* aPresContext);

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Разница между файлами не показана из-за своего большого размера Загрузить разницу

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

@ -27,7 +27,6 @@ nsLineBox::nsLineBox(nsIFrame* aFrame, PRInt32 aCount, PRUint16 flags)
mFirstChild = aFrame;
mChildCount = aCount;
mState = LINE_IS_DIRTY | flags;
mFloaters = nsnull;
mNext = nsnull;
mBounds.SetRect(0,0,0,0);
mCombinedArea.SetRect(0,0,0,0);
@ -39,19 +38,16 @@ nsLineBox::nsLineBox(nsIFrame* aFrame, PRInt32 aCount, PRUint16 flags)
nsLineBox::~nsLineBox()
{
if (nsnull != mFloaters) {
delete mFloaters;
}
}
static void
ListFloaters(FILE* out, PRInt32 aIndent, nsVoidArray* aFloaters)
ListFloaters(FILE* out, PRInt32 aIndent, const nsFloaterCacheList& aFloaters)
{
nsAutoString frameName;
PRInt32 j, i, n = aFloaters->Count();
for (i = 0; i < n; i++) {
for (j = aIndent; --j >= 0; ) fputs(" ", out);
nsPlaceholderFrame* ph = (nsPlaceholderFrame*) aFloaters->ElementAt(i);
nsFloaterCache* fc = aFloaters.Head();
while (fc) {
nsFrame::IndentBy(out, aIndent);
nsPlaceholderFrame* ph = fc->mPlaceholder;
if (nsnull != ph) {
fprintf(out, "placeholder@%p ", ph);
nsIFrame* frame = ph->GetOutOfFlowFrame();
@ -59,8 +55,13 @@ ListFloaters(FILE* out, PRInt32 aIndent, nsVoidArray* aFloaters)
frame->GetFrameName(frameName);
fputs(frameName, out);
}
fprintf(out, " %s region={%d,%d,%d,%d}",
fc->mIsCurrentLineFloater ? "cl" : "bcl",
fc->mRegion.x, fc->mRegion.y,
fc->mRegion.width, fc->mRegion.height);
fprintf(out, "\n");
}
fc = fc->Next();
}
}
@ -105,7 +106,7 @@ nsLineBox::List(FILE* out, PRInt32 aIndent) const
}
for (i = aIndent; --i >= 0; ) fputs(" ", out);
if (nsnull != mFloaters) {
if (mFloaters.NotEmpty()) {
fputs("> floaters <\n", out);
ListFloaters(out, aIndent + 1, mFloaters);
for (i = aIndent; --i >= 0; ) fputs(" ", out);
@ -463,3 +464,128 @@ nsLineIterator::FindFrameAt(PRInt32 aLineNumber,
*aFrameFound = frame;
return NS_OK;
}
//----------------------------------------------------------------------
nsFloaterCacheList::~nsFloaterCacheList()
{
nsFloaterCache* floater = mHead;
while (floater) {
nsFloaterCache* next = floater->mNext;
delete floater;
floater = next;
}
}
nsFloaterCache*
nsFloaterCacheList::Tail() const
{
nsFloaterCache* fc = mHead;
while (fc) {
if (!fc->mNext) {
break;
}
fc = fc->mNext;
}
return fc;
}
void
nsFloaterCacheList::Append(nsFloaterCacheFreeList& aList)
{
nsFloaterCache* tail = Tail();
if (tail) {
tail->mNext = aList.mHead;
}
else {
mHead = aList.mHead;
}
aList.mHead = nsnull;
aList.mTail = nsnull;
}
nsFloaterCache*
nsFloaterCacheList::Find(nsIFrame* aOutOfFlowFrame)
{
nsFloaterCache* fc = mHead;
while (fc) {
if (fc->mPlaceholder->GetOutOfFlowFrame() == aOutOfFlowFrame) {
break;
}
fc = fc->Next();
}
return fc;
}
void
nsFloaterCacheList::Remove(nsFloaterCache* aElement)
{
nsFloaterCache** fcp = &mHead;
nsFloaterCache* fc;
while (nsnull != (fc = *fcp)) {
if (fc == aElement) {
*fcp = fc->mNext;
break;
}
fcp = &fc->mNext;
}
}
//----------------------------------------------------------------------
void
nsFloaterCacheFreeList::Append(nsFloaterCacheList& aList)
{
if (mTail) {
mTail->mNext = aList.mHead;
}
else {
mHead = aList.mHead;
}
mTail = aList.Tail();
aList.mHead = nsnull;
}
nsFloaterCache*
nsFloaterCacheFreeList::Alloc()
{
nsFloaterCache* fc = mHead;
if (mHead) {
if (mHead == mTail) {
mHead = mTail = nsnull;
}
else {
mHead = fc->mNext;
}
fc->mNext = nsnull;
}
else {
fc = new nsFloaterCache();
}
return fc;
}
void
nsFloaterCacheFreeList::Append(nsFloaterCache* aFloater)
{
aFloater->mNext = nsnull;
if (mTail) {
mTail->mNext = aFloater;
mTail = aFloater;
}
else {
mHead = mTail = aFloater;
}
}
//----------------------------------------------------------------------
nsFloaterCache::nsFloaterCache()
: mPlaceholder(nsnull),
mIsCurrentLineFloater(PR_TRUE),
mMargins(0, 0, 0, 0),
mOffsets(0, 0, 0, 0),
mCombinedArea(0, 0, 0, 0),
mNext(nsnull)
{
}

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

@ -24,16 +24,117 @@
#include "nsILineIterator.h"
// bits in nsLineBox.mState
#define LINE_IS_DIRTY 0x1
#define LINE_IS_BLOCK 0x2
#define LINE_IS_DIRTY 0x1
#define LINE_IS_BLOCK 0x2
#define LINE_IS_IMPACTED_BY_FLOATER 0x4
#ifdef BLOCK_DOES_FIRST_LINE
#define LINE_IS_FIRST_LINE 0x4
#define LINE_IS_FIRST_LINE 0x8
#endif
#define LINE_WAS_DIRTY 0x8
#define LINE_WAS_DIRTY 0x10
class nsISpaceManager;
class nsLineBox;
//----------------------------------------------------------------------
class nsFloaterCache;
class nsFloaterCacheList;
class nsFloaterCacheFreeList;
// State cached after reflowing a floater. This state is used during
// incremental reflow when we avoid reflowing a floater.
class nsFloaterCache {
public:
nsFloaterCache();
~nsFloaterCache() { }
nsFloaterCache* Next() const { return mNext; }
nsPlaceholderFrame* mPlaceholder; // nsPlaceholderFrame
// This will be true if the floater was placed on the current line
// instead of below the current line.
PRBool mIsCurrentLineFloater;
nsMargin mMargins; // computed margins
nsMargin mOffsets; // computed offsets (relative pos)
// Region in the spacemanager impacted by this floater; the
// coordinates are relative to the containing block frame. The
// region includes the margins around the floater, but doesn't
// include the relative offsets.
nsRect mRegion;
// Combined area for the floater. This will not include the margins
// for the floater. Like mRegion, the coordinates are relative to
// the containing block frame.
nsRect mCombinedArea;
protected:
nsFloaterCache* mNext;
friend class nsFloaterCacheList;
friend class nsFloaterCacheFreeList;
};
//----------------------------------------
class nsFloaterCacheList {
public:
nsFloaterCacheList() : mHead(nsnull) { }
~nsFloaterCacheList();
PRBool IsEmpty() const {
return nsnull == mHead;
}
PRBool NotEmpty() const {
return nsnull != mHead;
}
nsFloaterCache* Head() const {
return mHead;
}
nsFloaterCache* Tail() const;
nsFloaterCache* Find(nsIFrame* aOutOfFlowFrame);
void Remove(nsFloaterCache* aElement);
void Append(nsFloaterCacheFreeList& aList);
protected:
nsFloaterCache* mHead;
friend class nsFloaterCacheFreeList;
};
//---------------------------------------
class nsFloaterCacheFreeList : public nsFloaterCacheList {
public:
nsFloaterCacheFreeList() : mTail(nsnull) { }
~nsFloaterCacheFreeList() { }
// Steal away aList's nsFloaterCache objects and put them on this
// free-list.
void Append(nsFloaterCacheList& aList);
void Append(nsFloaterCache* aFloaterCache);
// Allocate a new nsFloaterCache object
nsFloaterCache* Alloc();
protected:
nsFloaterCache* mTail;
friend class nsFloaterCacheList;
};
//----------------------------------------------------------------------
/**
* The nsLineBox class represents a horizontal line of frames. It contains
* enough state to support incremental reflow of the frames, event handling
@ -92,6 +193,19 @@ public:
}
}
void SetLineIsImpactedByFloater(PRBool aValue) {
if (aValue) {
mState |= LINE_IS_IMPACTED_BY_FLOATER;
}
else {
mState &= ~LINE_IS_IMPACTED_BY_FLOATER;
}
}
PRBool IsImpactedByFloater() const {
return 0 != (LINE_IS_IMPACTED_BY_FLOATER & mState);
}
#ifdef BLOCK_DOES_FIRST_LINE
PRBool IsFirstLine() const {
return 0 != (LINE_IS_FIRST_LINE & mState);
@ -150,7 +264,7 @@ public:
nsRect mBounds;
nsRect mCombinedArea;
nscoord mCarriedOutBottomMargin;/* XXX switch to 16 bits */
nsVoidArray* mFloaters;
nsFloaterCacheList mFloaters;
nsLineBox* mNext;
nscoord mMaxElementWidth; // width part of max-element-size
};