зеркало из 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);
|
||||
|
||||
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);
|
||||
mFirstChild = aFrame;
|
||||
mChildCount = aCount;
|
||||
|
||||
mAllFlags = 0;
|
||||
MarkDirty();
|
||||
SetIsBlock(aIsBlock);
|
||||
mNext = nsnull;
|
||||
mBounds.SetRect(0,0,0,0);
|
||||
mCombinedArea.SetRect(0,0,0,0);
|
||||
//XXX mCarriedOutTopMargin = 0;
|
||||
mCarriedOutBottomMargin = 0;
|
||||
#if NS_STYLE_CLEAR_NONE > 0
|
||||
mFlags.mBreakType = NS_STYLE_CLEAR_NONE;
|
||||
mMaxElementWidth = 0;
|
||||
#endif
|
||||
SetChildCount(aCount);
|
||||
MarkDirty();
|
||||
mFlags.mBlock = aIsBlock;
|
||||
}
|
||||
|
||||
nsLineBox::~nsLineBox()
|
||||
{
|
||||
MOZ_COUNT_DTOR(nsLineBox);
|
||||
|
||||
if (IsBlock()) {
|
||||
if (mBlockData) {
|
||||
delete mBlockData;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (mInlineData) {
|
||||
delete mInlineData;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -82,9 +94,11 @@ ListFloaters(FILE* out, PRInt32 aIndent, const nsFloaterCacheList& aFloaters)
|
|||
char*
|
||||
nsLineBox::StateToString(char* aBuf, PRInt32 aBufSize) const
|
||||
{
|
||||
PR_snprintf(aBuf, aBufSize, "%s,%s[0x%x]",
|
||||
IsDirty() ? "dirty" : "clean",
|
||||
PR_snprintf(aBuf, aBufSize, "%s,%s,%s,%s[0x%x]",
|
||||
IsBlock() ? "block" : "inline",
|
||||
IsDirty() ? "dirty" : "",
|
||||
IsImpactedByFloater() ? "impacted" : "",
|
||||
IsTrimmed() ? "trimmed" : "",
|
||||
mAllFlags);
|
||||
return aBuf;
|
||||
}
|
||||
|
@ -97,30 +111,33 @@ nsLineBox::List(FILE* out, PRInt32 aIndent) const
|
|||
for (i = aIndent; --i >= 0; ) fputs(" ", out);
|
||||
char cbuf[100];
|
||||
fprintf(out, "line %p: count=%d state=%s ",
|
||||
this, ChildCount(), StateToString(cbuf, sizeof(cbuf)));
|
||||
if (0 != mCarriedOutBottomMargin) {
|
||||
fprintf(out, "bm=%d ", mCarriedOutBottomMargin);
|
||||
this, GetChildCount(), StateToString(cbuf, sizeof(cbuf)));
|
||||
if (0 != GetCarriedOutBottomMargin()) {
|
||||
fprintf(out, "bm=%d ", GetCarriedOutBottomMargin());
|
||||
}
|
||||
if (0 != mMaxElementWidth) {
|
||||
fprintf(out, "mew=%d ", mMaxElementWidth);
|
||||
}
|
||||
fprintf(out, "{%d,%d,%d,%d} ca={%d,%d,%d,%d}",
|
||||
mBounds.x, mBounds.y, mBounds.width, mBounds.height,
|
||||
mCombinedArea.x, mCombinedArea.y,
|
||||
mCombinedArea.width, mCombinedArea.height);
|
||||
fprintf(out, " <\n");
|
||||
fprintf(out, "{%d,%d,%d,%d} ",
|
||||
mBounds.x, mBounds.y, mBounds.width, mBounds.height);
|
||||
if (mData) {
|
||||
fprintf(out, "ca={%d,%d,%d,%d} ",
|
||||
mData->mCombinedArea.x, mData->mCombinedArea.y,
|
||||
mData->mCombinedArea.width, mData->mCombinedArea.height);
|
||||
}
|
||||
fprintf(out, "<\n");
|
||||
|
||||
nsIFrame* frame = mFirstChild;
|
||||
PRInt32 n = ChildCount();
|
||||
PRInt32 n = GetChildCount();
|
||||
while (--n >= 0) {
|
||||
frame->List(out, aIndent + 1);
|
||||
frame->GetNextSibling(&frame);
|
||||
}
|
||||
|
||||
for (i = aIndent; --i >= 0; ) fputs(" ", out);
|
||||
if (mFloaters.NotEmpty()) {
|
||||
if (HasFloaters()) {
|
||||
fputs("> floaters <\n", out);
|
||||
ListFloaters(out, aIndent + 1, mFloaters);
|
||||
ListFloaters(out, aIndent + 1, mInlineData->mFloaters);
|
||||
for (i = aIndent; --i >= 0; ) fputs(" ", out);
|
||||
}
|
||||
fputs(">\n", out);
|
||||
|
@ -130,7 +147,7 @@ nsIFrame*
|
|||
nsLineBox::LastChild() const
|
||||
{
|
||||
nsIFrame* frame = mFirstChild;
|
||||
PRInt32 n = ChildCount() - 1;
|
||||
PRInt32 n = GetChildCount() - 1;
|
||||
while (--n >= 0) {
|
||||
frame->GetNextSibling(&frame);
|
||||
}
|
||||
|
@ -147,7 +164,7 @@ nsLineBox::IsLastChild(nsIFrame* aFrame) const
|
|||
PRInt32
|
||||
nsLineBox::IndexOf(nsIFrame* aFrame) const
|
||||
{
|
||||
PRInt32 i, n = ChildCount();
|
||||
PRInt32 i, n = GetChildCount();
|
||||
nsIFrame* frame = mFirstChild;
|
||||
for (i = 0; i < n; i++) {
|
||||
if (frame == aFrame) {
|
||||
|
@ -208,39 +225,172 @@ nsLineBox::FindLineContaining(nsLineBox* aLine, nsIFrame* aFrame,
|
|||
return nsnull;
|
||||
}
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
PRBool
|
||||
nsLineBox::CheckIsBlock() const
|
||||
nscoord
|
||||
nsLineBox::GetCarriedOutBottomMargin() const
|
||||
{
|
||||
PRBool isBlock = nsLineLayout::TreatFrameAsBlock(mFirstChild);
|
||||
return isBlock == IsBlock();
|
||||
return (IsBlock() && mBlockData) ? mBlockData->mCarriedOutBottomMargin : 0;
|
||||
}
|
||||
|
||||
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
|
||||
PRBool
|
||||
nsIAtom*
|
||||
nsLineBox::SizeOf(nsISizeOfHandler* aHandler, PRUint32* aResult) const
|
||||
{
|
||||
NS_PRECONDITION(aResult, "null OUT parameter pointer");
|
||||
*aResult = sizeof(*this);
|
||||
|
||||
PRBool big = PR_TRUE;
|
||||
if ((IsBlock() || mFloaters.IsEmpty()) &&
|
||||
(mBounds == mCombinedArea)) {
|
||||
big = PR_FALSE;
|
||||
nsIAtom* atom;
|
||||
if (IsBlock()) {
|
||||
atom = nsLayoutAtoms::lineBoxBlockSmall;
|
||||
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
|
||||
if (HasFloaters()) {
|
||||
PRUint32 floatersSize;
|
||||
mInlineData->mFloaters.SizeOf(aHandler, &floatersSize);
|
||||
|
||||
// Base size of embedded object was included in sizeof(*this) above
|
||||
floatersSize -= sizeof(mInlineData->mFloaters);
|
||||
aHandler->AddSize(nsLayoutAtoms::lineBoxFloaters, floatersSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add in the size needed for floaters associated with this line
|
||||
if (mFloaters.NotEmpty()) {
|
||||
PRUint32 floatersSize;
|
||||
|
||||
mFloaters.SizeOf(aHandler, &floatersSize);
|
||||
// Base size of embedded object was included in sizeof(*this) above
|
||||
floatersSize -= sizeof(mFloaters);
|
||||
aHandler->AddSize(nsLayoutAtoms::lineBoxFloaters, floatersSize);
|
||||
}
|
||||
|
||||
return big;
|
||||
return atom;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -346,7 +496,7 @@ nsLineIterator::GetLine(PRInt32 aLineNumber,
|
|||
}
|
||||
nsLineBox* line = mLines[aLineNumber];
|
||||
*aFirstFrameOnLine = line->mFirstChild;
|
||||
*aNumFramesOnLine = line->mChildCount;
|
||||
*aNumFramesOnLine = line->GetChildCount();
|
||||
aLineBounds = line->mBounds;
|
||||
|
||||
PRUint32 flags = 0;
|
||||
|
@ -462,7 +612,7 @@ nsLineIterator::FindFrameAt(PRInt32 aLineNumber,
|
|||
*aXIsAfterLastFrame = PR_FALSE;
|
||||
nsRect r1, r2;
|
||||
nsIFrame* frame = line->mFirstChild;
|
||||
PRInt32 n = line->mChildCount;
|
||||
PRInt32 n = line->GetChildCount();
|
||||
if (mRightToLeft) {
|
||||
while (--n >= 0) {
|
||||
nsIFrame* nextFrame;
|
||||
|
@ -528,6 +678,7 @@ nsFloaterCacheList::~nsFloaterCacheList()
|
|||
delete floater;
|
||||
floater = next;
|
||||
}
|
||||
mHead = nsnull;
|
||||
}
|
||||
|
||||
nsFloaterCache*
|
||||
|
|
|
@ -26,9 +26,6 @@
|
|||
|
||||
class nsISpaceManager;
|
||||
class nsLineBox;
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
class nsFloaterCache;
|
||||
class nsFloaterCacheList;
|
||||
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
|
||||
* enough state to support incremental reflow of the frames, event handling
|
||||
|
@ -145,44 +149,96 @@ public:
|
|||
nsLineBox(nsIFrame* aFrame, PRInt32 aCount, PRBool aIsBlock);
|
||||
~nsLineBox();
|
||||
|
||||
// mBlock bit
|
||||
PRBool IsBlock() const {
|
||||
return mFlags.mBlock;
|
||||
}
|
||||
|
||||
PRBool IsInline() const {
|
||||
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) {
|
||||
mFlags.mTrimmed = aOn;
|
||||
}
|
||||
|
||||
PRBool IsTrimmed() const {
|
||||
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 {
|
||||
return NS_STYLE_CLEAR_NONE != mFlags.mBreakType;
|
||||
}
|
||||
|
||||
void SetBreakType(PRUint8 aBreakType) {
|
||||
NS_WARN_IF_FALSE(aBreakType <= LINE_MAX_BREAK_TYPE, "bad break type");
|
||||
mFlags.mBreakType = aBreakType;
|
||||
}
|
||||
|
||||
PRUint8 GetBreakType() const {
|
||||
return mFlags.mBreakType;
|
||||
}
|
||||
|
||||
nscoord GetCarriedOutBottomMargin() const {
|
||||
return mCarriedOutBottomMargin;
|
||||
// mCarriedOutBottomMargin value
|
||||
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);
|
||||
|
||||
|
@ -193,38 +249,10 @@ public:
|
|||
|
||||
void List(FILE* out, PRInt32 aIndent) const;
|
||||
|
||||
PRInt32 ChildCount() const {
|
||||
return PRInt32(mChildCount);
|
||||
}
|
||||
|
||||
nsIFrame* LastChild() 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;
|
||||
|
||||
PRInt32 IndexOf(nsIFrame* aFrame) const;
|
||||
|
@ -233,21 +261,14 @@ public:
|
|||
return IndexOf(aFrame) >= 0;
|
||||
}
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
PRBool CheckIsBlock() const;
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
PRBool SizeOf(nsISizeOfHandler* aHandler, PRUint32* aResult) const;
|
||||
nsIAtom* SizeOf(nsISizeOfHandler* aHandler, PRUint32* aResult) const;
|
||||
#endif
|
||||
|
||||
nsIFrame* mFirstChild;
|
||||
PRUint16 mChildCount;
|
||||
nsRect mBounds;
|
||||
nsRect mCombinedArea;
|
||||
nscoord mCarriedOutBottomMargin;/* XXX switch to 16 bits */
|
||||
nsFloaterCacheList mFloaters;
|
||||
nsLineBox* mNext;
|
||||
|
||||
nsRect mBounds;
|
||||
nscoord mMaxElementWidth; // width part of max-element-size
|
||||
|
||||
struct FlagBits {
|
||||
|
@ -256,9 +277,28 @@ public:
|
|||
PRUint32 mImpactedByFloater : 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:
|
||||
|
@ -266,6 +306,14 @@ protected:
|
|||
PRUint32 mAllFlags;
|
||||
FlagBits mFlags;
|
||||
};
|
||||
|
||||
union {
|
||||
ExtraData* mData;
|
||||
ExtraBlockData* mBlockData;
|
||||
ExtraInlineData* mInlineData;
|
||||
};
|
||||
|
||||
void MaybeFreeData();
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -30,25 +30,37 @@
|
|||
MOZ_DECL_CTOR_COUNTER(nsLineBox);
|
||||
|
||||
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);
|
||||
mFirstChild = aFrame;
|
||||
mChildCount = aCount;
|
||||
|
||||
mAllFlags = 0;
|
||||
MarkDirty();
|
||||
SetIsBlock(aIsBlock);
|
||||
mNext = nsnull;
|
||||
mBounds.SetRect(0,0,0,0);
|
||||
mCombinedArea.SetRect(0,0,0,0);
|
||||
//XXX mCarriedOutTopMargin = 0;
|
||||
mCarriedOutBottomMargin = 0;
|
||||
#if NS_STYLE_CLEAR_NONE > 0
|
||||
mFlags.mBreakType = NS_STYLE_CLEAR_NONE;
|
||||
mMaxElementWidth = 0;
|
||||
#endif
|
||||
SetChildCount(aCount);
|
||||
MarkDirty();
|
||||
mFlags.mBlock = aIsBlock;
|
||||
}
|
||||
|
||||
nsLineBox::~nsLineBox()
|
||||
{
|
||||
MOZ_COUNT_DTOR(nsLineBox);
|
||||
|
||||
if (IsBlock()) {
|
||||
if (mBlockData) {
|
||||
delete mBlockData;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (mInlineData) {
|
||||
delete mInlineData;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -82,9 +94,11 @@ ListFloaters(FILE* out, PRInt32 aIndent, const nsFloaterCacheList& aFloaters)
|
|||
char*
|
||||
nsLineBox::StateToString(char* aBuf, PRInt32 aBufSize) const
|
||||
{
|
||||
PR_snprintf(aBuf, aBufSize, "%s,%s[0x%x]",
|
||||
IsDirty() ? "dirty" : "clean",
|
||||
PR_snprintf(aBuf, aBufSize, "%s,%s,%s,%s[0x%x]",
|
||||
IsBlock() ? "block" : "inline",
|
||||
IsDirty() ? "dirty" : "",
|
||||
IsImpactedByFloater() ? "impacted" : "",
|
||||
IsTrimmed() ? "trimmed" : "",
|
||||
mAllFlags);
|
||||
return aBuf;
|
||||
}
|
||||
|
@ -97,30 +111,33 @@ nsLineBox::List(FILE* out, PRInt32 aIndent) const
|
|||
for (i = aIndent; --i >= 0; ) fputs(" ", out);
|
||||
char cbuf[100];
|
||||
fprintf(out, "line %p: count=%d state=%s ",
|
||||
this, ChildCount(), StateToString(cbuf, sizeof(cbuf)));
|
||||
if (0 != mCarriedOutBottomMargin) {
|
||||
fprintf(out, "bm=%d ", mCarriedOutBottomMargin);
|
||||
this, GetChildCount(), StateToString(cbuf, sizeof(cbuf)));
|
||||
if (0 != GetCarriedOutBottomMargin()) {
|
||||
fprintf(out, "bm=%d ", GetCarriedOutBottomMargin());
|
||||
}
|
||||
if (0 != mMaxElementWidth) {
|
||||
fprintf(out, "mew=%d ", mMaxElementWidth);
|
||||
}
|
||||
fprintf(out, "{%d,%d,%d,%d} ca={%d,%d,%d,%d}",
|
||||
mBounds.x, mBounds.y, mBounds.width, mBounds.height,
|
||||
mCombinedArea.x, mCombinedArea.y,
|
||||
mCombinedArea.width, mCombinedArea.height);
|
||||
fprintf(out, " <\n");
|
||||
fprintf(out, "{%d,%d,%d,%d} ",
|
||||
mBounds.x, mBounds.y, mBounds.width, mBounds.height);
|
||||
if (mData) {
|
||||
fprintf(out, "ca={%d,%d,%d,%d} ",
|
||||
mData->mCombinedArea.x, mData->mCombinedArea.y,
|
||||
mData->mCombinedArea.width, mData->mCombinedArea.height);
|
||||
}
|
||||
fprintf(out, "<\n");
|
||||
|
||||
nsIFrame* frame = mFirstChild;
|
||||
PRInt32 n = ChildCount();
|
||||
PRInt32 n = GetChildCount();
|
||||
while (--n >= 0) {
|
||||
frame->List(out, aIndent + 1);
|
||||
frame->GetNextSibling(&frame);
|
||||
}
|
||||
|
||||
for (i = aIndent; --i >= 0; ) fputs(" ", out);
|
||||
if (mFloaters.NotEmpty()) {
|
||||
if (HasFloaters()) {
|
||||
fputs("> floaters <\n", out);
|
||||
ListFloaters(out, aIndent + 1, mFloaters);
|
||||
ListFloaters(out, aIndent + 1, mInlineData->mFloaters);
|
||||
for (i = aIndent; --i >= 0; ) fputs(" ", out);
|
||||
}
|
||||
fputs(">\n", out);
|
||||
|
@ -130,7 +147,7 @@ nsIFrame*
|
|||
nsLineBox::LastChild() const
|
||||
{
|
||||
nsIFrame* frame = mFirstChild;
|
||||
PRInt32 n = ChildCount() - 1;
|
||||
PRInt32 n = GetChildCount() - 1;
|
||||
while (--n >= 0) {
|
||||
frame->GetNextSibling(&frame);
|
||||
}
|
||||
|
@ -147,7 +164,7 @@ nsLineBox::IsLastChild(nsIFrame* aFrame) const
|
|||
PRInt32
|
||||
nsLineBox::IndexOf(nsIFrame* aFrame) const
|
||||
{
|
||||
PRInt32 i, n = ChildCount();
|
||||
PRInt32 i, n = GetChildCount();
|
||||
nsIFrame* frame = mFirstChild;
|
||||
for (i = 0; i < n; i++) {
|
||||
if (frame == aFrame) {
|
||||
|
@ -208,39 +225,172 @@ nsLineBox::FindLineContaining(nsLineBox* aLine, nsIFrame* aFrame,
|
|||
return nsnull;
|
||||
}
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
PRBool
|
||||
nsLineBox::CheckIsBlock() const
|
||||
nscoord
|
||||
nsLineBox::GetCarriedOutBottomMargin() const
|
||||
{
|
||||
PRBool isBlock = nsLineLayout::TreatFrameAsBlock(mFirstChild);
|
||||
return isBlock == IsBlock();
|
||||
return (IsBlock() && mBlockData) ? mBlockData->mCarriedOutBottomMargin : 0;
|
||||
}
|
||||
|
||||
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
|
||||
PRBool
|
||||
nsIAtom*
|
||||
nsLineBox::SizeOf(nsISizeOfHandler* aHandler, PRUint32* aResult) const
|
||||
{
|
||||
NS_PRECONDITION(aResult, "null OUT parameter pointer");
|
||||
*aResult = sizeof(*this);
|
||||
|
||||
PRBool big = PR_TRUE;
|
||||
if ((IsBlock() || mFloaters.IsEmpty()) &&
|
||||
(mBounds == mCombinedArea)) {
|
||||
big = PR_FALSE;
|
||||
nsIAtom* atom;
|
||||
if (IsBlock()) {
|
||||
atom = nsLayoutAtoms::lineBoxBlockSmall;
|
||||
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
|
||||
if (HasFloaters()) {
|
||||
PRUint32 floatersSize;
|
||||
mInlineData->mFloaters.SizeOf(aHandler, &floatersSize);
|
||||
|
||||
// Base size of embedded object was included in sizeof(*this) above
|
||||
floatersSize -= sizeof(mInlineData->mFloaters);
|
||||
aHandler->AddSize(nsLayoutAtoms::lineBoxFloaters, floatersSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add in the size needed for floaters associated with this line
|
||||
if (mFloaters.NotEmpty()) {
|
||||
PRUint32 floatersSize;
|
||||
|
||||
mFloaters.SizeOf(aHandler, &floatersSize);
|
||||
// Base size of embedded object was included in sizeof(*this) above
|
||||
floatersSize -= sizeof(mFloaters);
|
||||
aHandler->AddSize(nsLayoutAtoms::lineBoxFloaters, floatersSize);
|
||||
}
|
||||
|
||||
return big;
|
||||
return atom;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -346,7 +496,7 @@ nsLineIterator::GetLine(PRInt32 aLineNumber,
|
|||
}
|
||||
nsLineBox* line = mLines[aLineNumber];
|
||||
*aFirstFrameOnLine = line->mFirstChild;
|
||||
*aNumFramesOnLine = line->mChildCount;
|
||||
*aNumFramesOnLine = line->GetChildCount();
|
||||
aLineBounds = line->mBounds;
|
||||
|
||||
PRUint32 flags = 0;
|
||||
|
@ -462,7 +612,7 @@ nsLineIterator::FindFrameAt(PRInt32 aLineNumber,
|
|||
*aXIsAfterLastFrame = PR_FALSE;
|
||||
nsRect r1, r2;
|
||||
nsIFrame* frame = line->mFirstChild;
|
||||
PRInt32 n = line->mChildCount;
|
||||
PRInt32 n = line->GetChildCount();
|
||||
if (mRightToLeft) {
|
||||
while (--n >= 0) {
|
||||
nsIFrame* nextFrame;
|
||||
|
@ -528,6 +678,7 @@ nsFloaterCacheList::~nsFloaterCacheList()
|
|||
delete floater;
|
||||
floater = next;
|
||||
}
|
||||
mHead = nsnull;
|
||||
}
|
||||
|
||||
nsFloaterCache*
|
||||
|
|
|
@ -26,9 +26,6 @@
|
|||
|
||||
class nsISpaceManager;
|
||||
class nsLineBox;
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
class nsFloaterCache;
|
||||
class nsFloaterCacheList;
|
||||
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
|
||||
* enough state to support incremental reflow of the frames, event handling
|
||||
|
@ -145,44 +149,96 @@ public:
|
|||
nsLineBox(nsIFrame* aFrame, PRInt32 aCount, PRBool aIsBlock);
|
||||
~nsLineBox();
|
||||
|
||||
// mBlock bit
|
||||
PRBool IsBlock() const {
|
||||
return mFlags.mBlock;
|
||||
}
|
||||
|
||||
PRBool IsInline() const {
|
||||
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) {
|
||||
mFlags.mTrimmed = aOn;
|
||||
}
|
||||
|
||||
PRBool IsTrimmed() const {
|
||||
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 {
|
||||
return NS_STYLE_CLEAR_NONE != mFlags.mBreakType;
|
||||
}
|
||||
|
||||
void SetBreakType(PRUint8 aBreakType) {
|
||||
NS_WARN_IF_FALSE(aBreakType <= LINE_MAX_BREAK_TYPE, "bad break type");
|
||||
mFlags.mBreakType = aBreakType;
|
||||
}
|
||||
|
||||
PRUint8 GetBreakType() const {
|
||||
return mFlags.mBreakType;
|
||||
}
|
||||
|
||||
nscoord GetCarriedOutBottomMargin() const {
|
||||
return mCarriedOutBottomMargin;
|
||||
// mCarriedOutBottomMargin value
|
||||
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);
|
||||
|
||||
|
@ -193,38 +249,10 @@ public:
|
|||
|
||||
void List(FILE* out, PRInt32 aIndent) const;
|
||||
|
||||
PRInt32 ChildCount() const {
|
||||
return PRInt32(mChildCount);
|
||||
}
|
||||
|
||||
nsIFrame* LastChild() 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;
|
||||
|
||||
PRInt32 IndexOf(nsIFrame* aFrame) const;
|
||||
|
@ -233,21 +261,14 @@ public:
|
|||
return IndexOf(aFrame) >= 0;
|
||||
}
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
PRBool CheckIsBlock() const;
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
PRBool SizeOf(nsISizeOfHandler* aHandler, PRUint32* aResult) const;
|
||||
nsIAtom* SizeOf(nsISizeOfHandler* aHandler, PRUint32* aResult) const;
|
||||
#endif
|
||||
|
||||
nsIFrame* mFirstChild;
|
||||
PRUint16 mChildCount;
|
||||
nsRect mBounds;
|
||||
nsRect mCombinedArea;
|
||||
nscoord mCarriedOutBottomMargin;/* XXX switch to 16 bits */
|
||||
nsFloaterCacheList mFloaters;
|
||||
nsLineBox* mNext;
|
||||
|
||||
nsRect mBounds;
|
||||
nscoord mMaxElementWidth; // width part of max-element-size
|
||||
|
||||
struct FlagBits {
|
||||
|
@ -256,9 +277,28 @@ public:
|
|||
PRUint32 mImpactedByFloater : 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:
|
||||
|
@ -266,6 +306,14 @@ protected:
|
|||
PRUint32 mAllFlags;
|
||||
FlagBits mFlags;
|
||||
};
|
||||
|
||||
union {
|
||||
ExtraData* mData;
|
||||
ExtraBlockData* mBlockData;
|
||||
ExtraInlineData* mInlineData;
|
||||
};
|
||||
|
||||
void MaybeFreeData();
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
|
Загрузка…
Ссылка в новой задаче