зеркало из https://github.com/mozilla/gecko-dev.git
r=troy; Reworked nsLineBox api to allow for reduced storage overhead; fixed bug 16252 while keeping bug 12709 fixed
This commit is contained in:
Родитель
27ff1e76cb
Коммит
ab0a40b009
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -30,25 +30,37 @@
|
||||||
MOZ_DECL_CTOR_COUNTER(nsLineBox);
|
MOZ_DECL_CTOR_COUNTER(nsLineBox);
|
||||||
|
|
||||||
nsLineBox::nsLineBox(nsIFrame* aFrame, PRInt32 aCount, PRBool aIsBlock)
|
nsLineBox::nsLineBox(nsIFrame* aFrame, PRInt32 aCount, PRBool aIsBlock)
|
||||||
|
: mFirstChild(aFrame),
|
||||||
|
mNext(nsnull),
|
||||||
|
mBounds(0, 0, 0, 0),
|
||||||
|
mMaxElementWidth(0),
|
||||||
|
mData(nsnull)
|
||||||
{
|
{
|
||||||
MOZ_COUNT_CTOR(nsLineBox);
|
MOZ_COUNT_CTOR(nsLineBox);
|
||||||
mFirstChild = aFrame;
|
|
||||||
mChildCount = aCount;
|
|
||||||
mAllFlags = 0;
|
mAllFlags = 0;
|
||||||
MarkDirty();
|
#if NS_STYLE_CLEAR_NONE > 0
|
||||||
SetIsBlock(aIsBlock);
|
|
||||||
mNext = nsnull;
|
|
||||||
mBounds.SetRect(0,0,0,0);
|
|
||||||
mCombinedArea.SetRect(0,0,0,0);
|
|
||||||
//XXX mCarriedOutTopMargin = 0;
|
|
||||||
mCarriedOutBottomMargin = 0;
|
|
||||||
mFlags.mBreakType = NS_STYLE_CLEAR_NONE;
|
mFlags.mBreakType = NS_STYLE_CLEAR_NONE;
|
||||||
mMaxElementWidth = 0;
|
#endif
|
||||||
|
SetChildCount(aCount);
|
||||||
|
MarkDirty();
|
||||||
|
mFlags.mBlock = aIsBlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsLineBox::~nsLineBox()
|
nsLineBox::~nsLineBox()
|
||||||
{
|
{
|
||||||
MOZ_COUNT_DTOR(nsLineBox);
|
MOZ_COUNT_DTOR(nsLineBox);
|
||||||
|
|
||||||
|
if (IsBlock()) {
|
||||||
|
if (mBlockData) {
|
||||||
|
delete mBlockData;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (mInlineData) {
|
||||||
|
delete mInlineData;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -82,9 +94,11 @@ ListFloaters(FILE* out, PRInt32 aIndent, const nsFloaterCacheList& aFloaters)
|
||||||
char*
|
char*
|
||||||
nsLineBox::StateToString(char* aBuf, PRInt32 aBufSize) const
|
nsLineBox::StateToString(char* aBuf, PRInt32 aBufSize) const
|
||||||
{
|
{
|
||||||
PR_snprintf(aBuf, aBufSize, "%s,%s[0x%x]",
|
PR_snprintf(aBuf, aBufSize, "%s,%s,%s,%s[0x%x]",
|
||||||
IsDirty() ? "dirty" : "clean",
|
|
||||||
IsBlock() ? "block" : "inline",
|
IsBlock() ? "block" : "inline",
|
||||||
|
IsDirty() ? "dirty" : "",
|
||||||
|
IsImpactedByFloater() ? "impacted" : "",
|
||||||
|
IsTrimmed() ? "trimmed" : "",
|
||||||
mAllFlags);
|
mAllFlags);
|
||||||
return aBuf;
|
return aBuf;
|
||||||
}
|
}
|
||||||
|
@ -97,30 +111,33 @@ nsLineBox::List(FILE* out, PRInt32 aIndent) const
|
||||||
for (i = aIndent; --i >= 0; ) fputs(" ", out);
|
for (i = aIndent; --i >= 0; ) fputs(" ", out);
|
||||||
char cbuf[100];
|
char cbuf[100];
|
||||||
fprintf(out, "line %p: count=%d state=%s ",
|
fprintf(out, "line %p: count=%d state=%s ",
|
||||||
this, ChildCount(), StateToString(cbuf, sizeof(cbuf)));
|
this, GetChildCount(), StateToString(cbuf, sizeof(cbuf)));
|
||||||
if (0 != mCarriedOutBottomMargin) {
|
if (0 != GetCarriedOutBottomMargin()) {
|
||||||
fprintf(out, "bm=%d ", mCarriedOutBottomMargin);
|
fprintf(out, "bm=%d ", GetCarriedOutBottomMargin());
|
||||||
}
|
}
|
||||||
if (0 != mMaxElementWidth) {
|
if (0 != mMaxElementWidth) {
|
||||||
fprintf(out, "mew=%d ", mMaxElementWidth);
|
fprintf(out, "mew=%d ", mMaxElementWidth);
|
||||||
}
|
}
|
||||||
fprintf(out, "{%d,%d,%d,%d} ca={%d,%d,%d,%d}",
|
fprintf(out, "{%d,%d,%d,%d} ",
|
||||||
mBounds.x, mBounds.y, mBounds.width, mBounds.height,
|
mBounds.x, mBounds.y, mBounds.width, mBounds.height);
|
||||||
mCombinedArea.x, mCombinedArea.y,
|
if (mData) {
|
||||||
mCombinedArea.width, mCombinedArea.height);
|
fprintf(out, "ca={%d,%d,%d,%d} ",
|
||||||
fprintf(out, " <\n");
|
mData->mCombinedArea.x, mData->mCombinedArea.y,
|
||||||
|
mData->mCombinedArea.width, mData->mCombinedArea.height);
|
||||||
|
}
|
||||||
|
fprintf(out, "<\n");
|
||||||
|
|
||||||
nsIFrame* frame = mFirstChild;
|
nsIFrame* frame = mFirstChild;
|
||||||
PRInt32 n = ChildCount();
|
PRInt32 n = GetChildCount();
|
||||||
while (--n >= 0) {
|
while (--n >= 0) {
|
||||||
frame->List(out, aIndent + 1);
|
frame->List(out, aIndent + 1);
|
||||||
frame->GetNextSibling(&frame);
|
frame->GetNextSibling(&frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = aIndent; --i >= 0; ) fputs(" ", out);
|
for (i = aIndent; --i >= 0; ) fputs(" ", out);
|
||||||
if (mFloaters.NotEmpty()) {
|
if (HasFloaters()) {
|
||||||
fputs("> floaters <\n", out);
|
fputs("> floaters <\n", out);
|
||||||
ListFloaters(out, aIndent + 1, mFloaters);
|
ListFloaters(out, aIndent + 1, mInlineData->mFloaters);
|
||||||
for (i = aIndent; --i >= 0; ) fputs(" ", out);
|
for (i = aIndent; --i >= 0; ) fputs(" ", out);
|
||||||
}
|
}
|
||||||
fputs(">\n", out);
|
fputs(">\n", out);
|
||||||
|
@ -130,7 +147,7 @@ nsIFrame*
|
||||||
nsLineBox::LastChild() const
|
nsLineBox::LastChild() const
|
||||||
{
|
{
|
||||||
nsIFrame* frame = mFirstChild;
|
nsIFrame* frame = mFirstChild;
|
||||||
PRInt32 n = ChildCount() - 1;
|
PRInt32 n = GetChildCount() - 1;
|
||||||
while (--n >= 0) {
|
while (--n >= 0) {
|
||||||
frame->GetNextSibling(&frame);
|
frame->GetNextSibling(&frame);
|
||||||
}
|
}
|
||||||
|
@ -147,7 +164,7 @@ nsLineBox::IsLastChild(nsIFrame* aFrame) const
|
||||||
PRInt32
|
PRInt32
|
||||||
nsLineBox::IndexOf(nsIFrame* aFrame) const
|
nsLineBox::IndexOf(nsIFrame* aFrame) const
|
||||||
{
|
{
|
||||||
PRInt32 i, n = ChildCount();
|
PRInt32 i, n = GetChildCount();
|
||||||
nsIFrame* frame = mFirstChild;
|
nsIFrame* frame = mFirstChild;
|
||||||
for (i = 0; i < n; i++) {
|
for (i = 0; i < n; i++) {
|
||||||
if (frame == aFrame) {
|
if (frame == aFrame) {
|
||||||
|
@ -208,39 +225,172 @@ nsLineBox::FindLineContaining(nsLineBox* aLine, nsIFrame* aFrame,
|
||||||
return nsnull;
|
return nsnull;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef NS_DEBUG
|
nscoord
|
||||||
PRBool
|
nsLineBox::GetCarriedOutBottomMargin() const
|
||||||
nsLineBox::CheckIsBlock() const
|
|
||||||
{
|
{
|
||||||
PRBool isBlock = nsLineLayout::TreatFrameAsBlock(mFirstChild);
|
return (IsBlock() && mBlockData) ? mBlockData->mCarriedOutBottomMargin : 0;
|
||||||
return isBlock == IsBlock();
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsLineBox::SetCarriedOutBottomMargin(nscoord aValue)
|
||||||
|
{
|
||||||
|
if (IsBlock()) {
|
||||||
|
if (aValue) {
|
||||||
|
if (!mBlockData) {
|
||||||
|
mBlockData = new ExtraBlockData(mBounds);
|
||||||
|
}
|
||||||
|
if (mBlockData) {
|
||||||
|
mBlockData->mCarriedOutBottomMargin = aValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (mBlockData) {
|
||||||
|
mBlockData->mCarriedOutBottomMargin = aValue;
|
||||||
|
MaybeFreeData();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsLineBox::MaybeFreeData()
|
||||||
|
{
|
||||||
|
if (mData && (mData->mCombinedArea == mBounds)) {
|
||||||
|
if (IsInline()) {
|
||||||
|
if (mInlineData->mFloaters.IsEmpty()) {
|
||||||
|
delete mInlineData;
|
||||||
|
mInlineData = nsnull;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (0 == mBlockData->mCarriedOutBottomMargin) {
|
||||||
|
delete mBlockData;
|
||||||
|
mBlockData = nsnull;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// XXX get rid of this???
|
||||||
|
nsFloaterCache*
|
||||||
|
nsLineBox::GetFirstFloater()
|
||||||
|
{
|
||||||
|
if (NS_WARN_IF_FALSE(IsInline(), "block line can't have floaters")) {
|
||||||
|
return nsnull;
|
||||||
|
}
|
||||||
|
return mInlineData ? mInlineData->mFloaters.Head() : nsnull;
|
||||||
|
}
|
||||||
|
|
||||||
|
// XXX this might be too eager to free memory
|
||||||
|
void
|
||||||
|
nsLineBox::FreeFloaters(nsFloaterCacheFreeList& aFreeList)
|
||||||
|
{
|
||||||
|
NS_WARN_IF_FALSE(IsInline(), "block line can't have floaters");
|
||||||
|
if (IsInline()) {
|
||||||
|
if (mInlineData) {
|
||||||
|
aFreeList.Append(mInlineData->mFloaters);
|
||||||
|
MaybeFreeData();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsLineBox::AppendFloaters(nsFloaterCacheFreeList& aFreeList)
|
||||||
|
{
|
||||||
|
NS_WARN_IF_FALSE(IsInline(), "block line can't have floaters");
|
||||||
|
if (IsInline()) {
|
||||||
|
if (aFreeList.NotEmpty()) {
|
||||||
|
if (!mInlineData) {
|
||||||
|
mInlineData = new ExtraInlineData(mBounds);
|
||||||
|
}
|
||||||
|
if (mInlineData) {
|
||||||
|
mInlineData->mFloaters.Append(aFreeList);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PRBool
|
||||||
|
nsLineBox::RemoveFloater(nsIFrame* aFrame)
|
||||||
|
{
|
||||||
|
NS_WARN_IF_FALSE(IsInline(), "block line can't have floaters");
|
||||||
|
if (IsInline() && mInlineData) {
|
||||||
|
nsFloaterCache* fc = mInlineData->mFloaters.Find(aFrame);
|
||||||
|
if (fc) {
|
||||||
|
// Note: the placeholder is part of the line's child list
|
||||||
|
// and will be removed later.
|
||||||
|
fc->mPlaceholder->SetOutOfFlowFrame(nsnull);
|
||||||
|
mInlineData->mFloaters.Remove(fc);
|
||||||
|
MaybeFreeData();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return PR_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsLineBox::SetCombinedArea(const nsRect& aCombinedArea)
|
||||||
|
{
|
||||||
|
if (aCombinedArea != mBounds) {
|
||||||
|
if (mData) {
|
||||||
|
mData->mCombinedArea = aCombinedArea;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (IsInline()) {
|
||||||
|
mInlineData = new ExtraInlineData(aCombinedArea);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
mBlockData = new ExtraBlockData(aCombinedArea);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (mData) {
|
||||||
|
// Store away new value so that MaybeFreeData compares against
|
||||||
|
// the right value.
|
||||||
|
mData->mCombinedArea = aCombinedArea;
|
||||||
|
}
|
||||||
|
MaybeFreeData();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsLineBox::GetCombinedArea(nsRect* aResult)
|
||||||
|
{
|
||||||
|
if (aResult) {
|
||||||
|
*aResult = mData ? mData->mCombinedArea : mBounds;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
PRBool
|
nsIAtom*
|
||||||
nsLineBox::SizeOf(nsISizeOfHandler* aHandler, PRUint32* aResult) const
|
nsLineBox::SizeOf(nsISizeOfHandler* aHandler, PRUint32* aResult) const
|
||||||
{
|
{
|
||||||
NS_PRECONDITION(aResult, "null OUT parameter pointer");
|
NS_PRECONDITION(aResult, "null OUT parameter pointer");
|
||||||
*aResult = sizeof(*this);
|
*aResult = sizeof(*this);
|
||||||
|
|
||||||
PRBool big = PR_TRUE;
|
nsIAtom* atom;
|
||||||
if ((IsBlock() || mFloaters.IsEmpty()) &&
|
if (IsBlock()) {
|
||||||
(mBounds == mCombinedArea)) {
|
atom = nsLayoutAtoms::lineBoxBlockSmall;
|
||||||
big = PR_FALSE;
|
if (mBlockData) {
|
||||||
|
atom = nsLayoutAtoms::lineBoxBlockBig;
|
||||||
|
*aResult += sizeof(*mBlockData);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
atom = nsLayoutAtoms::lineBoxSmall;
|
||||||
|
if (mInlineData) {
|
||||||
|
atom = nsLayoutAtoms::lineBoxBig;
|
||||||
|
*aResult += sizeof(*mInlineData);
|
||||||
|
|
||||||
// Add in the size needed for floaters associated with this line
|
// Add in the size needed for floaters associated with this line
|
||||||
if (mFloaters.NotEmpty()) {
|
if (HasFloaters()) {
|
||||||
PRUint32 floatersSize;
|
PRUint32 floatersSize;
|
||||||
|
mInlineData->mFloaters.SizeOf(aHandler, &floatersSize);
|
||||||
|
|
||||||
mFloaters.SizeOf(aHandler, &floatersSize);
|
|
||||||
// Base size of embedded object was included in sizeof(*this) above
|
// Base size of embedded object was included in sizeof(*this) above
|
||||||
floatersSize -= sizeof(mFloaters);
|
floatersSize -= sizeof(mInlineData->mFloaters);
|
||||||
aHandler->AddSize(nsLayoutAtoms::lineBoxFloaters, floatersSize);
|
aHandler->AddSize(nsLayoutAtoms::lineBoxFloaters, floatersSize);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return big;
|
return atom;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -346,7 +496,7 @@ nsLineIterator::GetLine(PRInt32 aLineNumber,
|
||||||
}
|
}
|
||||||
nsLineBox* line = mLines[aLineNumber];
|
nsLineBox* line = mLines[aLineNumber];
|
||||||
*aFirstFrameOnLine = line->mFirstChild;
|
*aFirstFrameOnLine = line->mFirstChild;
|
||||||
*aNumFramesOnLine = line->mChildCount;
|
*aNumFramesOnLine = line->GetChildCount();
|
||||||
aLineBounds = line->mBounds;
|
aLineBounds = line->mBounds;
|
||||||
|
|
||||||
PRUint32 flags = 0;
|
PRUint32 flags = 0;
|
||||||
|
@ -462,7 +612,7 @@ nsLineIterator::FindFrameAt(PRInt32 aLineNumber,
|
||||||
*aXIsAfterLastFrame = PR_FALSE;
|
*aXIsAfterLastFrame = PR_FALSE;
|
||||||
nsRect r1, r2;
|
nsRect r1, r2;
|
||||||
nsIFrame* frame = line->mFirstChild;
|
nsIFrame* frame = line->mFirstChild;
|
||||||
PRInt32 n = line->mChildCount;
|
PRInt32 n = line->GetChildCount();
|
||||||
if (mRightToLeft) {
|
if (mRightToLeft) {
|
||||||
while (--n >= 0) {
|
while (--n >= 0) {
|
||||||
nsIFrame* nextFrame;
|
nsIFrame* nextFrame;
|
||||||
|
@ -528,6 +678,7 @@ nsFloaterCacheList::~nsFloaterCacheList()
|
||||||
delete floater;
|
delete floater;
|
||||||
floater = next;
|
floater = next;
|
||||||
}
|
}
|
||||||
|
mHead = nsnull;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsFloaterCache*
|
nsFloaterCache*
|
||||||
|
|
|
@ -26,9 +26,6 @@
|
||||||
|
|
||||||
class nsISpaceManager;
|
class nsISpaceManager;
|
||||||
class nsLineBox;
|
class nsLineBox;
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
|
||||||
|
|
||||||
class nsFloaterCache;
|
class nsFloaterCache;
|
||||||
class nsFloaterCacheList;
|
class nsFloaterCacheList;
|
||||||
class nsFloaterCacheFreeList;
|
class nsFloaterCacheFreeList;
|
||||||
|
@ -135,6 +132,13 @@ protected:
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
|
#define LINE_MAX_BREAK_TYPE ((1 << 4) - 1)
|
||||||
|
#define LINE_MAX_CHILD_COUNT ((1 << 24) - 1)
|
||||||
|
|
||||||
|
#if NS_STYLE_CLEAR_LAST_VALUE > 15
|
||||||
|
need to rearrange the mBits bitfield;
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The nsLineBox class represents a horizontal line of frames. It contains
|
* The nsLineBox class represents a horizontal line of frames. It contains
|
||||||
* enough state to support incremental reflow of the frames, event handling
|
* enough state to support incremental reflow of the frames, event handling
|
||||||
|
@ -145,44 +149,96 @@ public:
|
||||||
nsLineBox(nsIFrame* aFrame, PRInt32 aCount, PRBool aIsBlock);
|
nsLineBox(nsIFrame* aFrame, PRInt32 aCount, PRBool aIsBlock);
|
||||||
~nsLineBox();
|
~nsLineBox();
|
||||||
|
|
||||||
|
// mBlock bit
|
||||||
PRBool IsBlock() const {
|
PRBool IsBlock() const {
|
||||||
return mFlags.mBlock;
|
return mFlags.mBlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
PRBool IsInline() const {
|
PRBool IsInline() const {
|
||||||
return 0 == mFlags.mBlock;
|
return 0 == mFlags.mBlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
// XXX Turn into a bit-field to simplify this code
|
// mDirty bit
|
||||||
|
void MarkDirty() {
|
||||||
|
mFlags.mDirty = 1;
|
||||||
|
}
|
||||||
|
void ClearDirty() {
|
||||||
|
mFlags.mDirty = 0;
|
||||||
|
}
|
||||||
|
PRBool IsDirty() const {
|
||||||
|
return mFlags.mDirty;
|
||||||
|
}
|
||||||
|
|
||||||
|
// mImpactedByFloater bit
|
||||||
|
void SetLineIsImpactedByFloater(PRBool aValue) {
|
||||||
|
mFlags.mImpactedByFloater = aValue;
|
||||||
|
}
|
||||||
|
PRBool IsImpactedByFloater() const {
|
||||||
|
return mFlags.mImpactedByFloater;
|
||||||
|
}
|
||||||
|
|
||||||
|
// mTrimmed bit
|
||||||
void SetTrimmed(PRBool aOn) {
|
void SetTrimmed(PRBool aOn) {
|
||||||
mFlags.mTrimmed = aOn;
|
mFlags.mTrimmed = aOn;
|
||||||
}
|
}
|
||||||
|
|
||||||
PRBool IsTrimmed() const {
|
PRBool IsTrimmed() const {
|
||||||
return mFlags.mTrimmed;
|
return mFlags.mTrimmed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// mChildCount value
|
||||||
|
PRInt32 GetChildCount() const {
|
||||||
|
return (PRInt32) mFlags.mChildCount;
|
||||||
|
}
|
||||||
|
void SetChildCount(PRInt32 aNewCount) {
|
||||||
|
if (NS_WARN_IF_FALSE(aNewCount >= 0, "negative child count")) {
|
||||||
|
aNewCount = 0;
|
||||||
|
}
|
||||||
|
if (aNewCount > LINE_MAX_CHILD_COUNT) {
|
||||||
|
aNewCount = LINE_MAX_CHILD_COUNT;
|
||||||
|
}
|
||||||
|
mFlags.mChildCount = aNewCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
// mBreakType value
|
||||||
PRBool HasBreak() const {
|
PRBool HasBreak() const {
|
||||||
return NS_STYLE_CLEAR_NONE != mFlags.mBreakType;
|
return NS_STYLE_CLEAR_NONE != mFlags.mBreakType;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetBreakType(PRUint8 aBreakType) {
|
void SetBreakType(PRUint8 aBreakType) {
|
||||||
|
NS_WARN_IF_FALSE(aBreakType <= LINE_MAX_BREAK_TYPE, "bad break type");
|
||||||
mFlags.mBreakType = aBreakType;
|
mFlags.mBreakType = aBreakType;
|
||||||
}
|
}
|
||||||
|
|
||||||
PRUint8 GetBreakType() const {
|
PRUint8 GetBreakType() const {
|
||||||
return mFlags.mBreakType;
|
return mFlags.mBreakType;
|
||||||
}
|
}
|
||||||
|
|
||||||
nscoord GetCarriedOutBottomMargin() const {
|
// mCarriedOutBottomMargin value
|
||||||
return mCarriedOutBottomMargin;
|
nscoord GetCarriedOutBottomMargin() const;
|
||||||
|
void SetCarriedOutBottomMargin(nscoord aValue);
|
||||||
|
|
||||||
|
// mFloaters
|
||||||
|
PRBool HasFloaters() const {
|
||||||
|
return (IsInline() && mInlineData) && mInlineData->mFloaters.NotEmpty();
|
||||||
|
}
|
||||||
|
nsFloaterCache* GetFirstFloater();
|
||||||
|
void FreeFloaters(nsFloaterCacheFreeList& aFreeList);
|
||||||
|
void AppendFloaters(nsFloaterCacheFreeList& aFreeList);
|
||||||
|
PRBool RemoveFloater(nsIFrame* aFrame);
|
||||||
|
|
||||||
|
void SetCombinedArea(const nsRect& aCombinedArea);
|
||||||
|
|
||||||
|
void GetCombinedArea(nsRect* aResult);
|
||||||
|
|
||||||
|
void SlideBy(nscoord aDY) {
|
||||||
|
mBounds.y += aDY;
|
||||||
|
if (mData) {
|
||||||
|
mData->mCombinedArea.y += aDY;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nscoord GetHeight() const { return mBounds.height; }
|
//----------------------------------------
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
|
||||||
// XXX old junk
|
|
||||||
|
|
||||||
|
nscoord GetHeight() const {
|
||||||
|
return mBounds.height;
|
||||||
|
}
|
||||||
|
|
||||||
static void DeleteLineList(nsIPresContext& aPresContext, nsLineBox* aLine);
|
static void DeleteLineList(nsIPresContext& aPresContext, nsLineBox* aLine);
|
||||||
|
|
||||||
|
@ -193,38 +249,10 @@ public:
|
||||||
|
|
||||||
void List(FILE* out, PRInt32 aIndent) const;
|
void List(FILE* out, PRInt32 aIndent) const;
|
||||||
|
|
||||||
PRInt32 ChildCount() const {
|
|
||||||
return PRInt32(mChildCount);
|
|
||||||
}
|
|
||||||
|
|
||||||
nsIFrame* LastChild() const;
|
nsIFrame* LastChild() const;
|
||||||
|
|
||||||
PRBool IsLastChild(nsIFrame* aFrame) const;
|
PRBool IsLastChild(nsIFrame* aFrame) const;
|
||||||
|
|
||||||
void SetIsBlock(PRBool aValue) {
|
|
||||||
mFlags.mBlock = aValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetLineIsImpactedByFloater(PRBool aValue) {
|
|
||||||
mFlags.mImpactedByFloater = aValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
PRBool IsImpactedByFloater() const {
|
|
||||||
return mFlags.mImpactedByFloater;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MarkDirty() {
|
|
||||||
mFlags.mDirty = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ClearDirty() {
|
|
||||||
mFlags.mDirty = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
PRBool IsDirty() const {
|
|
||||||
return mFlags.mDirty;
|
|
||||||
}
|
|
||||||
|
|
||||||
char* StateToString(char* aBuf, PRInt32 aBufSize) const;
|
char* StateToString(char* aBuf, PRInt32 aBufSize) const;
|
||||||
|
|
||||||
PRInt32 IndexOf(nsIFrame* aFrame) const;
|
PRInt32 IndexOf(nsIFrame* aFrame) const;
|
||||||
|
@ -233,21 +261,14 @@ public:
|
||||||
return IndexOf(aFrame) >= 0;
|
return IndexOf(aFrame) >= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef NS_DEBUG
|
|
||||||
PRBool CheckIsBlock() const;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
PRBool SizeOf(nsISizeOfHandler* aHandler, PRUint32* aResult) const;
|
nsIAtom* SizeOf(nsISizeOfHandler* aHandler, PRUint32* aResult) const;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
nsIFrame* mFirstChild;
|
nsIFrame* mFirstChild;
|
||||||
PRUint16 mChildCount;
|
|
||||||
nsRect mBounds;
|
|
||||||
nsRect mCombinedArea;
|
|
||||||
nscoord mCarriedOutBottomMargin;/* XXX switch to 16 bits */
|
|
||||||
nsFloaterCacheList mFloaters;
|
|
||||||
nsLineBox* mNext;
|
nsLineBox* mNext;
|
||||||
|
|
||||||
|
nsRect mBounds;
|
||||||
nscoord mMaxElementWidth; // width part of max-element-size
|
nscoord mMaxElementWidth; // width part of max-element-size
|
||||||
|
|
||||||
struct FlagBits {
|
struct FlagBits {
|
||||||
|
@ -256,9 +277,28 @@ public:
|
||||||
PRUint32 mImpactedByFloater : 1;
|
PRUint32 mImpactedByFloater : 1;
|
||||||
PRUint32 mTrimmed : 1;
|
PRUint32 mTrimmed : 1;
|
||||||
|
|
||||||
PRUint32 reserved : 20;
|
PRUint32 mBreakType : 4;
|
||||||
|
|
||||||
PRUint32 mBreakType : 8;
|
PRUint32 mChildCount : 24;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ExtraData {
|
||||||
|
ExtraData(const nsRect& aBounds) : mCombinedArea(aBounds) {
|
||||||
|
}
|
||||||
|
nsRect mCombinedArea;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ExtraBlockData : public ExtraData {
|
||||||
|
ExtraBlockData(const nsRect& aBounds) : ExtraData(aBounds) {
|
||||||
|
mCarriedOutBottomMargin = 0;
|
||||||
|
}
|
||||||
|
nscoord mCarriedOutBottomMargin;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ExtraInlineData : public ExtraData {
|
||||||
|
ExtraInlineData(const nsRect& aBounds) : ExtraData(aBounds) {
|
||||||
|
}
|
||||||
|
nsFloaterCacheList mFloaters;
|
||||||
};
|
};
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -266,6 +306,14 @@ protected:
|
||||||
PRUint32 mAllFlags;
|
PRUint32 mAllFlags;
|
||||||
FlagBits mFlags;
|
FlagBits mFlags;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
union {
|
||||||
|
ExtraData* mData;
|
||||||
|
ExtraBlockData* mBlockData;
|
||||||
|
ExtraInlineData* mInlineData;
|
||||||
|
};
|
||||||
|
|
||||||
|
void MaybeFreeData();
|
||||||
};
|
};
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -30,25 +30,37 @@
|
||||||
MOZ_DECL_CTOR_COUNTER(nsLineBox);
|
MOZ_DECL_CTOR_COUNTER(nsLineBox);
|
||||||
|
|
||||||
nsLineBox::nsLineBox(nsIFrame* aFrame, PRInt32 aCount, PRBool aIsBlock)
|
nsLineBox::nsLineBox(nsIFrame* aFrame, PRInt32 aCount, PRBool aIsBlock)
|
||||||
|
: mFirstChild(aFrame),
|
||||||
|
mNext(nsnull),
|
||||||
|
mBounds(0, 0, 0, 0),
|
||||||
|
mMaxElementWidth(0),
|
||||||
|
mData(nsnull)
|
||||||
{
|
{
|
||||||
MOZ_COUNT_CTOR(nsLineBox);
|
MOZ_COUNT_CTOR(nsLineBox);
|
||||||
mFirstChild = aFrame;
|
|
||||||
mChildCount = aCount;
|
|
||||||
mAllFlags = 0;
|
mAllFlags = 0;
|
||||||
MarkDirty();
|
#if NS_STYLE_CLEAR_NONE > 0
|
||||||
SetIsBlock(aIsBlock);
|
|
||||||
mNext = nsnull;
|
|
||||||
mBounds.SetRect(0,0,0,0);
|
|
||||||
mCombinedArea.SetRect(0,0,0,0);
|
|
||||||
//XXX mCarriedOutTopMargin = 0;
|
|
||||||
mCarriedOutBottomMargin = 0;
|
|
||||||
mFlags.mBreakType = NS_STYLE_CLEAR_NONE;
|
mFlags.mBreakType = NS_STYLE_CLEAR_NONE;
|
||||||
mMaxElementWidth = 0;
|
#endif
|
||||||
|
SetChildCount(aCount);
|
||||||
|
MarkDirty();
|
||||||
|
mFlags.mBlock = aIsBlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsLineBox::~nsLineBox()
|
nsLineBox::~nsLineBox()
|
||||||
{
|
{
|
||||||
MOZ_COUNT_DTOR(nsLineBox);
|
MOZ_COUNT_DTOR(nsLineBox);
|
||||||
|
|
||||||
|
if (IsBlock()) {
|
||||||
|
if (mBlockData) {
|
||||||
|
delete mBlockData;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (mInlineData) {
|
||||||
|
delete mInlineData;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -82,9 +94,11 @@ ListFloaters(FILE* out, PRInt32 aIndent, const nsFloaterCacheList& aFloaters)
|
||||||
char*
|
char*
|
||||||
nsLineBox::StateToString(char* aBuf, PRInt32 aBufSize) const
|
nsLineBox::StateToString(char* aBuf, PRInt32 aBufSize) const
|
||||||
{
|
{
|
||||||
PR_snprintf(aBuf, aBufSize, "%s,%s[0x%x]",
|
PR_snprintf(aBuf, aBufSize, "%s,%s,%s,%s[0x%x]",
|
||||||
IsDirty() ? "dirty" : "clean",
|
|
||||||
IsBlock() ? "block" : "inline",
|
IsBlock() ? "block" : "inline",
|
||||||
|
IsDirty() ? "dirty" : "",
|
||||||
|
IsImpactedByFloater() ? "impacted" : "",
|
||||||
|
IsTrimmed() ? "trimmed" : "",
|
||||||
mAllFlags);
|
mAllFlags);
|
||||||
return aBuf;
|
return aBuf;
|
||||||
}
|
}
|
||||||
|
@ -97,30 +111,33 @@ nsLineBox::List(FILE* out, PRInt32 aIndent) const
|
||||||
for (i = aIndent; --i >= 0; ) fputs(" ", out);
|
for (i = aIndent; --i >= 0; ) fputs(" ", out);
|
||||||
char cbuf[100];
|
char cbuf[100];
|
||||||
fprintf(out, "line %p: count=%d state=%s ",
|
fprintf(out, "line %p: count=%d state=%s ",
|
||||||
this, ChildCount(), StateToString(cbuf, sizeof(cbuf)));
|
this, GetChildCount(), StateToString(cbuf, sizeof(cbuf)));
|
||||||
if (0 != mCarriedOutBottomMargin) {
|
if (0 != GetCarriedOutBottomMargin()) {
|
||||||
fprintf(out, "bm=%d ", mCarriedOutBottomMargin);
|
fprintf(out, "bm=%d ", GetCarriedOutBottomMargin());
|
||||||
}
|
}
|
||||||
if (0 != mMaxElementWidth) {
|
if (0 != mMaxElementWidth) {
|
||||||
fprintf(out, "mew=%d ", mMaxElementWidth);
|
fprintf(out, "mew=%d ", mMaxElementWidth);
|
||||||
}
|
}
|
||||||
fprintf(out, "{%d,%d,%d,%d} ca={%d,%d,%d,%d}",
|
fprintf(out, "{%d,%d,%d,%d} ",
|
||||||
mBounds.x, mBounds.y, mBounds.width, mBounds.height,
|
mBounds.x, mBounds.y, mBounds.width, mBounds.height);
|
||||||
mCombinedArea.x, mCombinedArea.y,
|
if (mData) {
|
||||||
mCombinedArea.width, mCombinedArea.height);
|
fprintf(out, "ca={%d,%d,%d,%d} ",
|
||||||
fprintf(out, " <\n");
|
mData->mCombinedArea.x, mData->mCombinedArea.y,
|
||||||
|
mData->mCombinedArea.width, mData->mCombinedArea.height);
|
||||||
|
}
|
||||||
|
fprintf(out, "<\n");
|
||||||
|
|
||||||
nsIFrame* frame = mFirstChild;
|
nsIFrame* frame = mFirstChild;
|
||||||
PRInt32 n = ChildCount();
|
PRInt32 n = GetChildCount();
|
||||||
while (--n >= 0) {
|
while (--n >= 0) {
|
||||||
frame->List(out, aIndent + 1);
|
frame->List(out, aIndent + 1);
|
||||||
frame->GetNextSibling(&frame);
|
frame->GetNextSibling(&frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = aIndent; --i >= 0; ) fputs(" ", out);
|
for (i = aIndent; --i >= 0; ) fputs(" ", out);
|
||||||
if (mFloaters.NotEmpty()) {
|
if (HasFloaters()) {
|
||||||
fputs("> floaters <\n", out);
|
fputs("> floaters <\n", out);
|
||||||
ListFloaters(out, aIndent + 1, mFloaters);
|
ListFloaters(out, aIndent + 1, mInlineData->mFloaters);
|
||||||
for (i = aIndent; --i >= 0; ) fputs(" ", out);
|
for (i = aIndent; --i >= 0; ) fputs(" ", out);
|
||||||
}
|
}
|
||||||
fputs(">\n", out);
|
fputs(">\n", out);
|
||||||
|
@ -130,7 +147,7 @@ nsIFrame*
|
||||||
nsLineBox::LastChild() const
|
nsLineBox::LastChild() const
|
||||||
{
|
{
|
||||||
nsIFrame* frame = mFirstChild;
|
nsIFrame* frame = mFirstChild;
|
||||||
PRInt32 n = ChildCount() - 1;
|
PRInt32 n = GetChildCount() - 1;
|
||||||
while (--n >= 0) {
|
while (--n >= 0) {
|
||||||
frame->GetNextSibling(&frame);
|
frame->GetNextSibling(&frame);
|
||||||
}
|
}
|
||||||
|
@ -147,7 +164,7 @@ nsLineBox::IsLastChild(nsIFrame* aFrame) const
|
||||||
PRInt32
|
PRInt32
|
||||||
nsLineBox::IndexOf(nsIFrame* aFrame) const
|
nsLineBox::IndexOf(nsIFrame* aFrame) const
|
||||||
{
|
{
|
||||||
PRInt32 i, n = ChildCount();
|
PRInt32 i, n = GetChildCount();
|
||||||
nsIFrame* frame = mFirstChild;
|
nsIFrame* frame = mFirstChild;
|
||||||
for (i = 0; i < n; i++) {
|
for (i = 0; i < n; i++) {
|
||||||
if (frame == aFrame) {
|
if (frame == aFrame) {
|
||||||
|
@ -208,39 +225,172 @@ nsLineBox::FindLineContaining(nsLineBox* aLine, nsIFrame* aFrame,
|
||||||
return nsnull;
|
return nsnull;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef NS_DEBUG
|
nscoord
|
||||||
PRBool
|
nsLineBox::GetCarriedOutBottomMargin() const
|
||||||
nsLineBox::CheckIsBlock() const
|
|
||||||
{
|
{
|
||||||
PRBool isBlock = nsLineLayout::TreatFrameAsBlock(mFirstChild);
|
return (IsBlock() && mBlockData) ? mBlockData->mCarriedOutBottomMargin : 0;
|
||||||
return isBlock == IsBlock();
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsLineBox::SetCarriedOutBottomMargin(nscoord aValue)
|
||||||
|
{
|
||||||
|
if (IsBlock()) {
|
||||||
|
if (aValue) {
|
||||||
|
if (!mBlockData) {
|
||||||
|
mBlockData = new ExtraBlockData(mBounds);
|
||||||
|
}
|
||||||
|
if (mBlockData) {
|
||||||
|
mBlockData->mCarriedOutBottomMargin = aValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (mBlockData) {
|
||||||
|
mBlockData->mCarriedOutBottomMargin = aValue;
|
||||||
|
MaybeFreeData();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsLineBox::MaybeFreeData()
|
||||||
|
{
|
||||||
|
if (mData && (mData->mCombinedArea == mBounds)) {
|
||||||
|
if (IsInline()) {
|
||||||
|
if (mInlineData->mFloaters.IsEmpty()) {
|
||||||
|
delete mInlineData;
|
||||||
|
mInlineData = nsnull;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (0 == mBlockData->mCarriedOutBottomMargin) {
|
||||||
|
delete mBlockData;
|
||||||
|
mBlockData = nsnull;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// XXX get rid of this???
|
||||||
|
nsFloaterCache*
|
||||||
|
nsLineBox::GetFirstFloater()
|
||||||
|
{
|
||||||
|
if (NS_WARN_IF_FALSE(IsInline(), "block line can't have floaters")) {
|
||||||
|
return nsnull;
|
||||||
|
}
|
||||||
|
return mInlineData ? mInlineData->mFloaters.Head() : nsnull;
|
||||||
|
}
|
||||||
|
|
||||||
|
// XXX this might be too eager to free memory
|
||||||
|
void
|
||||||
|
nsLineBox::FreeFloaters(nsFloaterCacheFreeList& aFreeList)
|
||||||
|
{
|
||||||
|
NS_WARN_IF_FALSE(IsInline(), "block line can't have floaters");
|
||||||
|
if (IsInline()) {
|
||||||
|
if (mInlineData) {
|
||||||
|
aFreeList.Append(mInlineData->mFloaters);
|
||||||
|
MaybeFreeData();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsLineBox::AppendFloaters(nsFloaterCacheFreeList& aFreeList)
|
||||||
|
{
|
||||||
|
NS_WARN_IF_FALSE(IsInline(), "block line can't have floaters");
|
||||||
|
if (IsInline()) {
|
||||||
|
if (aFreeList.NotEmpty()) {
|
||||||
|
if (!mInlineData) {
|
||||||
|
mInlineData = new ExtraInlineData(mBounds);
|
||||||
|
}
|
||||||
|
if (mInlineData) {
|
||||||
|
mInlineData->mFloaters.Append(aFreeList);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PRBool
|
||||||
|
nsLineBox::RemoveFloater(nsIFrame* aFrame)
|
||||||
|
{
|
||||||
|
NS_WARN_IF_FALSE(IsInline(), "block line can't have floaters");
|
||||||
|
if (IsInline() && mInlineData) {
|
||||||
|
nsFloaterCache* fc = mInlineData->mFloaters.Find(aFrame);
|
||||||
|
if (fc) {
|
||||||
|
// Note: the placeholder is part of the line's child list
|
||||||
|
// and will be removed later.
|
||||||
|
fc->mPlaceholder->SetOutOfFlowFrame(nsnull);
|
||||||
|
mInlineData->mFloaters.Remove(fc);
|
||||||
|
MaybeFreeData();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return PR_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsLineBox::SetCombinedArea(const nsRect& aCombinedArea)
|
||||||
|
{
|
||||||
|
if (aCombinedArea != mBounds) {
|
||||||
|
if (mData) {
|
||||||
|
mData->mCombinedArea = aCombinedArea;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (IsInline()) {
|
||||||
|
mInlineData = new ExtraInlineData(aCombinedArea);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
mBlockData = new ExtraBlockData(aCombinedArea);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (mData) {
|
||||||
|
// Store away new value so that MaybeFreeData compares against
|
||||||
|
// the right value.
|
||||||
|
mData->mCombinedArea = aCombinedArea;
|
||||||
|
}
|
||||||
|
MaybeFreeData();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsLineBox::GetCombinedArea(nsRect* aResult)
|
||||||
|
{
|
||||||
|
if (aResult) {
|
||||||
|
*aResult = mData ? mData->mCombinedArea : mBounds;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
PRBool
|
nsIAtom*
|
||||||
nsLineBox::SizeOf(nsISizeOfHandler* aHandler, PRUint32* aResult) const
|
nsLineBox::SizeOf(nsISizeOfHandler* aHandler, PRUint32* aResult) const
|
||||||
{
|
{
|
||||||
NS_PRECONDITION(aResult, "null OUT parameter pointer");
|
NS_PRECONDITION(aResult, "null OUT parameter pointer");
|
||||||
*aResult = sizeof(*this);
|
*aResult = sizeof(*this);
|
||||||
|
|
||||||
PRBool big = PR_TRUE;
|
nsIAtom* atom;
|
||||||
if ((IsBlock() || mFloaters.IsEmpty()) &&
|
if (IsBlock()) {
|
||||||
(mBounds == mCombinedArea)) {
|
atom = nsLayoutAtoms::lineBoxBlockSmall;
|
||||||
big = PR_FALSE;
|
if (mBlockData) {
|
||||||
|
atom = nsLayoutAtoms::lineBoxBlockBig;
|
||||||
|
*aResult += sizeof(*mBlockData);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
atom = nsLayoutAtoms::lineBoxSmall;
|
||||||
|
if (mInlineData) {
|
||||||
|
atom = nsLayoutAtoms::lineBoxBig;
|
||||||
|
*aResult += sizeof(*mInlineData);
|
||||||
|
|
||||||
// Add in the size needed for floaters associated with this line
|
// Add in the size needed for floaters associated with this line
|
||||||
if (mFloaters.NotEmpty()) {
|
if (HasFloaters()) {
|
||||||
PRUint32 floatersSize;
|
PRUint32 floatersSize;
|
||||||
|
mInlineData->mFloaters.SizeOf(aHandler, &floatersSize);
|
||||||
|
|
||||||
mFloaters.SizeOf(aHandler, &floatersSize);
|
|
||||||
// Base size of embedded object was included in sizeof(*this) above
|
// Base size of embedded object was included in sizeof(*this) above
|
||||||
floatersSize -= sizeof(mFloaters);
|
floatersSize -= sizeof(mInlineData->mFloaters);
|
||||||
aHandler->AddSize(nsLayoutAtoms::lineBoxFloaters, floatersSize);
|
aHandler->AddSize(nsLayoutAtoms::lineBoxFloaters, floatersSize);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return big;
|
return atom;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -346,7 +496,7 @@ nsLineIterator::GetLine(PRInt32 aLineNumber,
|
||||||
}
|
}
|
||||||
nsLineBox* line = mLines[aLineNumber];
|
nsLineBox* line = mLines[aLineNumber];
|
||||||
*aFirstFrameOnLine = line->mFirstChild;
|
*aFirstFrameOnLine = line->mFirstChild;
|
||||||
*aNumFramesOnLine = line->mChildCount;
|
*aNumFramesOnLine = line->GetChildCount();
|
||||||
aLineBounds = line->mBounds;
|
aLineBounds = line->mBounds;
|
||||||
|
|
||||||
PRUint32 flags = 0;
|
PRUint32 flags = 0;
|
||||||
|
@ -462,7 +612,7 @@ nsLineIterator::FindFrameAt(PRInt32 aLineNumber,
|
||||||
*aXIsAfterLastFrame = PR_FALSE;
|
*aXIsAfterLastFrame = PR_FALSE;
|
||||||
nsRect r1, r2;
|
nsRect r1, r2;
|
||||||
nsIFrame* frame = line->mFirstChild;
|
nsIFrame* frame = line->mFirstChild;
|
||||||
PRInt32 n = line->mChildCount;
|
PRInt32 n = line->GetChildCount();
|
||||||
if (mRightToLeft) {
|
if (mRightToLeft) {
|
||||||
while (--n >= 0) {
|
while (--n >= 0) {
|
||||||
nsIFrame* nextFrame;
|
nsIFrame* nextFrame;
|
||||||
|
@ -528,6 +678,7 @@ nsFloaterCacheList::~nsFloaterCacheList()
|
||||||
delete floater;
|
delete floater;
|
||||||
floater = next;
|
floater = next;
|
||||||
}
|
}
|
||||||
|
mHead = nsnull;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsFloaterCache*
|
nsFloaterCache*
|
||||||
|
|
|
@ -26,9 +26,6 @@
|
||||||
|
|
||||||
class nsISpaceManager;
|
class nsISpaceManager;
|
||||||
class nsLineBox;
|
class nsLineBox;
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
|
||||||
|
|
||||||
class nsFloaterCache;
|
class nsFloaterCache;
|
||||||
class nsFloaterCacheList;
|
class nsFloaterCacheList;
|
||||||
class nsFloaterCacheFreeList;
|
class nsFloaterCacheFreeList;
|
||||||
|
@ -135,6 +132,13 @@ protected:
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
|
#define LINE_MAX_BREAK_TYPE ((1 << 4) - 1)
|
||||||
|
#define LINE_MAX_CHILD_COUNT ((1 << 24) - 1)
|
||||||
|
|
||||||
|
#if NS_STYLE_CLEAR_LAST_VALUE > 15
|
||||||
|
need to rearrange the mBits bitfield;
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The nsLineBox class represents a horizontal line of frames. It contains
|
* The nsLineBox class represents a horizontal line of frames. It contains
|
||||||
* enough state to support incremental reflow of the frames, event handling
|
* enough state to support incremental reflow of the frames, event handling
|
||||||
|
@ -145,44 +149,96 @@ public:
|
||||||
nsLineBox(nsIFrame* aFrame, PRInt32 aCount, PRBool aIsBlock);
|
nsLineBox(nsIFrame* aFrame, PRInt32 aCount, PRBool aIsBlock);
|
||||||
~nsLineBox();
|
~nsLineBox();
|
||||||
|
|
||||||
|
// mBlock bit
|
||||||
PRBool IsBlock() const {
|
PRBool IsBlock() const {
|
||||||
return mFlags.mBlock;
|
return mFlags.mBlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
PRBool IsInline() const {
|
PRBool IsInline() const {
|
||||||
return 0 == mFlags.mBlock;
|
return 0 == mFlags.mBlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
// XXX Turn into a bit-field to simplify this code
|
// mDirty bit
|
||||||
|
void MarkDirty() {
|
||||||
|
mFlags.mDirty = 1;
|
||||||
|
}
|
||||||
|
void ClearDirty() {
|
||||||
|
mFlags.mDirty = 0;
|
||||||
|
}
|
||||||
|
PRBool IsDirty() const {
|
||||||
|
return mFlags.mDirty;
|
||||||
|
}
|
||||||
|
|
||||||
|
// mImpactedByFloater bit
|
||||||
|
void SetLineIsImpactedByFloater(PRBool aValue) {
|
||||||
|
mFlags.mImpactedByFloater = aValue;
|
||||||
|
}
|
||||||
|
PRBool IsImpactedByFloater() const {
|
||||||
|
return mFlags.mImpactedByFloater;
|
||||||
|
}
|
||||||
|
|
||||||
|
// mTrimmed bit
|
||||||
void SetTrimmed(PRBool aOn) {
|
void SetTrimmed(PRBool aOn) {
|
||||||
mFlags.mTrimmed = aOn;
|
mFlags.mTrimmed = aOn;
|
||||||
}
|
}
|
||||||
|
|
||||||
PRBool IsTrimmed() const {
|
PRBool IsTrimmed() const {
|
||||||
return mFlags.mTrimmed;
|
return mFlags.mTrimmed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// mChildCount value
|
||||||
|
PRInt32 GetChildCount() const {
|
||||||
|
return (PRInt32) mFlags.mChildCount;
|
||||||
|
}
|
||||||
|
void SetChildCount(PRInt32 aNewCount) {
|
||||||
|
if (NS_WARN_IF_FALSE(aNewCount >= 0, "negative child count")) {
|
||||||
|
aNewCount = 0;
|
||||||
|
}
|
||||||
|
if (aNewCount > LINE_MAX_CHILD_COUNT) {
|
||||||
|
aNewCount = LINE_MAX_CHILD_COUNT;
|
||||||
|
}
|
||||||
|
mFlags.mChildCount = aNewCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
// mBreakType value
|
||||||
PRBool HasBreak() const {
|
PRBool HasBreak() const {
|
||||||
return NS_STYLE_CLEAR_NONE != mFlags.mBreakType;
|
return NS_STYLE_CLEAR_NONE != mFlags.mBreakType;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetBreakType(PRUint8 aBreakType) {
|
void SetBreakType(PRUint8 aBreakType) {
|
||||||
|
NS_WARN_IF_FALSE(aBreakType <= LINE_MAX_BREAK_TYPE, "bad break type");
|
||||||
mFlags.mBreakType = aBreakType;
|
mFlags.mBreakType = aBreakType;
|
||||||
}
|
}
|
||||||
|
|
||||||
PRUint8 GetBreakType() const {
|
PRUint8 GetBreakType() const {
|
||||||
return mFlags.mBreakType;
|
return mFlags.mBreakType;
|
||||||
}
|
}
|
||||||
|
|
||||||
nscoord GetCarriedOutBottomMargin() const {
|
// mCarriedOutBottomMargin value
|
||||||
return mCarriedOutBottomMargin;
|
nscoord GetCarriedOutBottomMargin() const;
|
||||||
|
void SetCarriedOutBottomMargin(nscoord aValue);
|
||||||
|
|
||||||
|
// mFloaters
|
||||||
|
PRBool HasFloaters() const {
|
||||||
|
return (IsInline() && mInlineData) && mInlineData->mFloaters.NotEmpty();
|
||||||
|
}
|
||||||
|
nsFloaterCache* GetFirstFloater();
|
||||||
|
void FreeFloaters(nsFloaterCacheFreeList& aFreeList);
|
||||||
|
void AppendFloaters(nsFloaterCacheFreeList& aFreeList);
|
||||||
|
PRBool RemoveFloater(nsIFrame* aFrame);
|
||||||
|
|
||||||
|
void SetCombinedArea(const nsRect& aCombinedArea);
|
||||||
|
|
||||||
|
void GetCombinedArea(nsRect* aResult);
|
||||||
|
|
||||||
|
void SlideBy(nscoord aDY) {
|
||||||
|
mBounds.y += aDY;
|
||||||
|
if (mData) {
|
||||||
|
mData->mCombinedArea.y += aDY;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nscoord GetHeight() const { return mBounds.height; }
|
//----------------------------------------
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
|
||||||
// XXX old junk
|
|
||||||
|
|
||||||
|
nscoord GetHeight() const {
|
||||||
|
return mBounds.height;
|
||||||
|
}
|
||||||
|
|
||||||
static void DeleteLineList(nsIPresContext& aPresContext, nsLineBox* aLine);
|
static void DeleteLineList(nsIPresContext& aPresContext, nsLineBox* aLine);
|
||||||
|
|
||||||
|
@ -193,38 +249,10 @@ public:
|
||||||
|
|
||||||
void List(FILE* out, PRInt32 aIndent) const;
|
void List(FILE* out, PRInt32 aIndent) const;
|
||||||
|
|
||||||
PRInt32 ChildCount() const {
|
|
||||||
return PRInt32(mChildCount);
|
|
||||||
}
|
|
||||||
|
|
||||||
nsIFrame* LastChild() const;
|
nsIFrame* LastChild() const;
|
||||||
|
|
||||||
PRBool IsLastChild(nsIFrame* aFrame) const;
|
PRBool IsLastChild(nsIFrame* aFrame) const;
|
||||||
|
|
||||||
void SetIsBlock(PRBool aValue) {
|
|
||||||
mFlags.mBlock = aValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetLineIsImpactedByFloater(PRBool aValue) {
|
|
||||||
mFlags.mImpactedByFloater = aValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
PRBool IsImpactedByFloater() const {
|
|
||||||
return mFlags.mImpactedByFloater;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MarkDirty() {
|
|
||||||
mFlags.mDirty = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ClearDirty() {
|
|
||||||
mFlags.mDirty = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
PRBool IsDirty() const {
|
|
||||||
return mFlags.mDirty;
|
|
||||||
}
|
|
||||||
|
|
||||||
char* StateToString(char* aBuf, PRInt32 aBufSize) const;
|
char* StateToString(char* aBuf, PRInt32 aBufSize) const;
|
||||||
|
|
||||||
PRInt32 IndexOf(nsIFrame* aFrame) const;
|
PRInt32 IndexOf(nsIFrame* aFrame) const;
|
||||||
|
@ -233,21 +261,14 @@ public:
|
||||||
return IndexOf(aFrame) >= 0;
|
return IndexOf(aFrame) >= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef NS_DEBUG
|
|
||||||
PRBool CheckIsBlock() const;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
PRBool SizeOf(nsISizeOfHandler* aHandler, PRUint32* aResult) const;
|
nsIAtom* SizeOf(nsISizeOfHandler* aHandler, PRUint32* aResult) const;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
nsIFrame* mFirstChild;
|
nsIFrame* mFirstChild;
|
||||||
PRUint16 mChildCount;
|
|
||||||
nsRect mBounds;
|
|
||||||
nsRect mCombinedArea;
|
|
||||||
nscoord mCarriedOutBottomMargin;/* XXX switch to 16 bits */
|
|
||||||
nsFloaterCacheList mFloaters;
|
|
||||||
nsLineBox* mNext;
|
nsLineBox* mNext;
|
||||||
|
|
||||||
|
nsRect mBounds;
|
||||||
nscoord mMaxElementWidth; // width part of max-element-size
|
nscoord mMaxElementWidth; // width part of max-element-size
|
||||||
|
|
||||||
struct FlagBits {
|
struct FlagBits {
|
||||||
|
@ -256,9 +277,28 @@ public:
|
||||||
PRUint32 mImpactedByFloater : 1;
|
PRUint32 mImpactedByFloater : 1;
|
||||||
PRUint32 mTrimmed : 1;
|
PRUint32 mTrimmed : 1;
|
||||||
|
|
||||||
PRUint32 reserved : 20;
|
PRUint32 mBreakType : 4;
|
||||||
|
|
||||||
PRUint32 mBreakType : 8;
|
PRUint32 mChildCount : 24;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ExtraData {
|
||||||
|
ExtraData(const nsRect& aBounds) : mCombinedArea(aBounds) {
|
||||||
|
}
|
||||||
|
nsRect mCombinedArea;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ExtraBlockData : public ExtraData {
|
||||||
|
ExtraBlockData(const nsRect& aBounds) : ExtraData(aBounds) {
|
||||||
|
mCarriedOutBottomMargin = 0;
|
||||||
|
}
|
||||||
|
nscoord mCarriedOutBottomMargin;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ExtraInlineData : public ExtraData {
|
||||||
|
ExtraInlineData(const nsRect& aBounds) : ExtraData(aBounds) {
|
||||||
|
}
|
||||||
|
nsFloaterCacheList mFloaters;
|
||||||
};
|
};
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -266,6 +306,14 @@ protected:
|
||||||
PRUint32 mAllFlags;
|
PRUint32 mAllFlags;
|
||||||
FlagBits mFlags;
|
FlagBits mFlags;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
union {
|
||||||
|
ExtraData* mData;
|
||||||
|
ExtraBlockData* mBlockData;
|
||||||
|
ExtraInlineData* mInlineData;
|
||||||
|
};
|
||||||
|
|
||||||
|
void MaybeFreeData();
|
||||||
};
|
};
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
|
|
Загрузка…
Ссылка в новой задаче