1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 // vim:cindent:ts=2:et:sw=2:
3 /* ***** BEGIN LICENSE BLOCK *****
4 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
6 * The contents of this file are subject to the Mozilla Public License Version
7 * 1.1 (the "License"); you may not use this file except in compliance with
8 * the License. You may obtain a copy of the License at
9 * http://www.mozilla.org/MPL/
11 * Software distributed under the License is distributed on an "AS IS" basis,
12 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13 * for the specific language governing rights and limitations under the
16 * The Original Code is Mozilla Communicator client code.
18 * The Initial Developer of the Original Code is
19 * Netscape Communications Corporation.
20 * Portions created by the Initial Developer are Copyright (C) 1998
21 * the Initial Developer. All Rights Reserved.
24 * L. David Baron <dbaron@dbaron.org>
25 * Pierre Phaneuf <pp@ludusdesign.com>
27 * Alternatively, the contents of this file may be used under the terms of
28 * either of the GNU General Public License Version 2 or later (the "GPL"),
29 * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
30 * in which case the provisions of the GPL or the LGPL are applicable instead
31 * of those above. If you wish to allow use of your version of this file only
32 * under the terms of either the GPL or the LGPL, and not to allow others to
33 * use your version of this file under the terms of the MPL, indicate your
34 * decision by deleting the provisions above and replace them with the notice
35 * and other provisions required by the GPL or the LGPL. If you do not delete
36 * the provisions above, a recipient may use your version of this file under
37 * the terms of any one of the MPL, the GPL or the LGPL.
39 * ***** END LICENSE BLOCK ***** */
41 /* representation of one line within a block frame, a CSS line box */
43 #include "nsLineBox.h"
44 #include "nsSpaceManager.h"
45 #include "nsLineLayout.h"
47 #include "nsBlockFrame.h"
48 #include "nsGkAtoms.h"
49 #include "nsFrameManager.h"
51 #include "nsBidiPresUtils.h"
55 static PRInt32 ctorCount
;
56 PRInt32
nsLineBox::GetCtorCount() { return ctorCount
; }
59 nsLineBox::nsLineBox(nsIFrame
* aFrame
, PRInt32 aCount
, PRBool aIsBlock
)
60 : mFirstChild(aFrame
),
64 MOZ_COUNT_CTOR(nsLineBox
);
67 NS_ASSERTION(!aIsBlock
|| aCount
== 1, "Blocks must have exactly one child");
69 for (PRInt32 n
= aCount
; n
> 0; f
= f
->GetNextSibling(), --n
) {
70 NS_ASSERTION(aIsBlock
== f
->GetStyleDisplay()->IsBlockOutside(),
71 "wrong kind of child frame");
76 #if NS_STYLE_CLEAR_NONE > 0
77 mFlags
.mBreakType
= NS_STYLE_CLEAR_NONE
;
79 SetChildCount(aCount
);
81 mFlags
.mBlock
= aIsBlock
;
84 nsLineBox::~nsLineBox()
86 MOZ_COUNT_DTOR(nsLineBox
);
91 NS_NewLineBox(nsIPresShell
* aPresShell
, nsIFrame
* aFrame
,
92 PRInt32 aCount
, PRBool aIsBlock
)
94 return new (aPresShell
)nsLineBox(aFrame
, aCount
, aIsBlock
);
97 // Overloaded new operator. Uses an arena (which comes from the presShell)
98 // to perform the allocation.
100 nsLineBox::operator new(size_t sz
, nsIPresShell
* aPresShell
) CPP_THROW_NEW
102 return aPresShell
->AllocateFrame(sz
);
105 // Overloaded delete operator. Doesn't actually free the memory, because we
108 nsLineBox::operator delete(void* aPtr
, size_t sz
)
113 nsLineBox::Destroy(nsIPresShell
* aPresShell
)
115 // Destroy the object. This won't actually free the memory, though
118 // Have the pres shell recycle the memory
119 aPresShell
->FreeFrame(sizeof(*this), (void*)this);
138 ListFloats(FILE* out
, PRInt32 aIndent
, const nsFloatCacheList
& aFloats
)
140 nsAutoString frameName
;
141 nsFloatCache
* fc
= aFloats
.Head();
143 nsFrame::IndentBy(out
, aIndent
);
144 nsPlaceholderFrame
* ph
= fc
->mPlaceholder
;
146 fprintf(out
, "placeholder@%p ", static_cast<void*>(ph
));
147 nsIFrame
* frame
= ph
->GetOutOfFlowFrame();
149 nsIFrameDebug
* frameDebug
;
151 if (NS_SUCCEEDED(frame
->QueryInterface(NS_GET_IID(nsIFrameDebug
), (void**)&frameDebug
))) {
152 frameDebug
->GetFrameName(frameName
);
153 fputs(NS_LossyConvertUTF16toASCII(frameName
).get(), out
);
156 fprintf(out
, " region={%d,%d,%d,%d}",
157 fc
->mRegion
.x
, fc
->mRegion
.y
,
158 fc
->mRegion
.width
, fc
->mRegion
.height
);
161 fputs("\n###!!! NULL out-of-flow frame", out
);
172 BreakTypeToString(PRUint8 aBreakType
)
174 switch (aBreakType
) {
175 case NS_STYLE_CLEAR_NONE
: return "nobr";
176 case NS_STYLE_CLEAR_LEFT
: return "leftbr";
177 case NS_STYLE_CLEAR_RIGHT
: return "rightbr";
178 case NS_STYLE_CLEAR_LEFT_AND_RIGHT
: return "leftbr+rightbr";
179 case NS_STYLE_CLEAR_LINE
: return "linebr";
180 case NS_STYLE_CLEAR_BLOCK
: return "blockbr";
181 case NS_STYLE_CLEAR_COLUMN
: return "columnbr";
182 case NS_STYLE_CLEAR_PAGE
: return "pagebr";
190 nsLineBox::StateToString(char* aBuf
, PRInt32 aBufSize
) const
192 PR_snprintf(aBuf
, aBufSize
, "%s,%s,%s,%s,%s,before:%s,after:%s[0x%x]",
193 IsBlock() ? "block" : "inline",
194 IsDirty() ? "dirty" : "clean",
195 IsPreviousMarginDirty() ? "prevmargindirty" : "prevmarginclean",
196 IsImpactedByFloat() ? "impacted" : "not impacted",
197 IsLineWrapped() ? "wrapped" : "not wrapped",
198 BreakTypeToString(GetBreakTypeBefore()),
199 BreakTypeToString(GetBreakTypeAfter()),
205 nsLineBox::List(FILE* out
, PRInt32 aIndent
) const
209 for (i
= aIndent
; --i
>= 0; ) fputs(" ", out
);
211 fprintf(out
, "line %p: count=%d state=%s ",
212 static_cast<const void*>(this), GetChildCount(),
213 StateToString(cbuf
, sizeof(cbuf
)));
214 if (IsBlock() && !GetCarriedOutBottomMargin().IsZero()) {
215 fprintf(out
, "bm=%d ", GetCarriedOutBottomMargin().get());
217 fprintf(out
, "{%d,%d,%d,%d} ",
218 mBounds
.x
, mBounds
.y
, mBounds
.width
, mBounds
.height
);
220 fprintf(out
, "ca={%d,%d,%d,%d} ",
221 mData
->mCombinedArea
.x
, mData
->mCombinedArea
.y
,
222 mData
->mCombinedArea
.width
, mData
->mCombinedArea
.height
);
226 nsIFrame
* frame
= mFirstChild
;
227 PRInt32 n
= GetChildCount();
229 nsIFrameDebug
* frameDebug
;
231 if (NS_SUCCEEDED(frame
->QueryInterface(NS_GET_IID(nsIFrameDebug
), (void**)&frameDebug
))) {
232 frameDebug
->List(out
, aIndent
+ 1);
234 frame
= frame
->GetNextSibling();
237 for (i
= aIndent
; --i
>= 0; ) fputs(" ", out
);
239 fputs("> floats <\n", out
);
240 ListFloats(out
, aIndent
+ 1, mInlineData
->mFloats
);
241 for (i
= aIndent
; --i
>= 0; ) fputs(" ", out
);
248 nsLineBox::LastChild() const
250 nsIFrame
* frame
= mFirstChild
;
251 PRInt32 n
= GetChildCount() - 1;
253 frame
= frame
->GetNextSibling();
259 nsLineBox::IsLastChild(nsIFrame
* aFrame
) const
261 nsIFrame
* lastFrame
= LastChild();
262 return aFrame
== lastFrame
;
266 nsLineBox::IndexOf(nsIFrame
* aFrame
) const
268 PRInt32 i
, n
= GetChildCount();
269 nsIFrame
* frame
= mFirstChild
;
270 for (i
= 0; i
< n
; i
++) {
271 if (frame
== aFrame
) {
274 frame
= frame
->GetNextSibling();
280 nsLineBox::IsEmpty() const
283 return mFirstChild
->IsEmpty();
287 for (n
= GetChildCount(), kid
= mFirstChild
;
289 --n
, kid
= kid
->GetNextSibling())
298 nsLineBox::CachedIsEmpty()
304 if (mFlags
.mEmptyCacheValid
) {
305 return mFlags
.mEmptyCacheState
;
310 result
= mFirstChild
->CachedIsEmpty();
315 for (n
= GetChildCount(), kid
= mFirstChild
;
317 --n
, kid
= kid
->GetNextSibling())
319 if (!kid
->CachedIsEmpty()) {
326 mFlags
.mEmptyCacheValid
= PR_TRUE
;
327 mFlags
.mEmptyCacheState
= result
;
332 nsLineBox::DeleteLineList(nsPresContext
* aPresContext
, nsLineList
& aLines
)
334 if (! aLines
.empty()) {
335 // Delete our child frames before doing anything else. In particular
336 // we do all of this before our base class releases it's hold on the
338 for (nsIFrame
* child
= aLines
.front()->mFirstChild
; child
; ) {
339 nsIFrame
* nextChild
= child
->GetNextSibling();
344 nsIPresShell
*shell
= aPresContext
->PresShell();
347 nsLineBox
* line
= aLines
.front();
349 line
->Destroy(shell
);
350 } while (! aLines
.empty());
355 nsLineBox::FindLineContaining(nsLineList
& aLines
, nsIFrame
* aFrame
,
356 PRInt32
* aFrameIndexInLine
)
358 NS_PRECONDITION(aFrameIndexInLine
&& !aLines
.empty() && aFrame
, "null ptr");
359 for (nsLineList::iterator line
= aLines
.begin(),
360 line_end
= aLines
.end();
364 PRInt32 ix
= line
->IndexOf(aFrame
);
366 *aFrameIndexInLine
= ix
;
370 *aFrameIndexInLine
= -1;
375 nsLineBox::RFindLineContaining(nsIFrame
* aFrame
,
376 const nsLineList::iterator
& aBegin
,
377 nsLineList::iterator
& aEnd
,
378 PRInt32
* aFrameIndexInLine
)
380 NS_PRECONDITION(aFrame
, "null ptr");
381 while (aBegin
!= aEnd
) {
383 PRInt32 ix
= aEnd
->IndexOf(aFrame
);
385 *aFrameIndexInLine
= ix
;
389 *aFrameIndexInLine
= -1;
394 nsLineBox::GetCarriedOutBottomMargin() const
396 NS_ASSERTION(IsBlock(),
397 "GetCarriedOutBottomMargin called on non-block line.");
398 return (IsBlock() && mBlockData
)
399 ? mBlockData
->mCarriedOutBottomMargin
400 : nsCollapsingMargin();
404 nsLineBox::SetCarriedOutBottomMargin(nsCollapsingMargin aValue
)
406 PRBool changed
= PR_FALSE
;
408 if (!aValue
.IsZero()) {
410 mBlockData
= new ExtraBlockData(mBounds
);
413 changed
= aValue
!= mBlockData
->mCarriedOutBottomMargin
;
414 mBlockData
->mCarriedOutBottomMargin
= aValue
;
417 else if (mBlockData
) {
418 changed
= aValue
!= mBlockData
->mCarriedOutBottomMargin
;
419 mBlockData
->mCarriedOutBottomMargin
= aValue
;
427 nsLineBox::MaybeFreeData()
429 if (mData
&& (mData
->mCombinedArea
== mBounds
)) {
431 if (mInlineData
->mFloats
.IsEmpty()) {
433 mInlineData
= nsnull
;
436 else if (mBlockData
->mCarriedOutBottomMargin
.IsZero()) {
443 // XXX get rid of this???
445 nsLineBox::GetFirstFloat()
447 NS_ABORT_IF_FALSE(IsInline(), "block line can't have floats");
448 return mInlineData
? mInlineData
->mFloats
.Head() : nsnull
;
451 // XXX this might be too eager to free memory
453 nsLineBox::FreeFloats(nsFloatCacheFreeList
& aFreeList
)
455 NS_ABORT_IF_FALSE(IsInline(), "block line can't have floats");
456 if (IsInline() && mInlineData
) {
457 if (mInlineData
->mFloats
.NotEmpty()) {
458 aFreeList
.Append(mInlineData
->mFloats
);
465 nsLineBox::AppendFloats(nsFloatCacheFreeList
& aFreeList
)
467 NS_ABORT_IF_FALSE(IsInline(), "block line can't have floats");
469 if (aFreeList
.NotEmpty()) {
471 mInlineData
= new ExtraInlineData(mBounds
);
474 mInlineData
->mFloats
.Append(aFreeList
);
481 nsLineBox::RemoveFloat(nsIFrame
* aFrame
)
483 NS_ABORT_IF_FALSE(IsInline(), "block line can't have floats");
484 if (IsInline() && mInlineData
) {
485 nsFloatCache
* fc
= mInlineData
->mFloats
.Find(aFrame
);
487 // Note: the placeholder is part of the line's child list
488 // and will be removed later.
489 mInlineData
->mFloats
.Remove(fc
);
499 nsLineBox::SetCombinedArea(const nsRect
& aCombinedArea
)
501 NS_ASSERTION(aCombinedArea
.width
>= 0, "illegal width for combined area");
502 NS_ASSERTION(aCombinedArea
.height
>= 0, "illegal height for combined area");
503 if (aCombinedArea
!= mBounds
) {
505 mData
->mCombinedArea
= aCombinedArea
;
509 mInlineData
= new ExtraInlineData(aCombinedArea
);
512 mBlockData
= new ExtraBlockData(aCombinedArea
);
518 // Store away new value so that MaybeFreeData compares against
520 mData
->mCombinedArea
= aCombinedArea
;
526 //----------------------------------------------------------------------
529 static nsLineBox
* gDummyLines
[1];
531 nsLineIterator::nsLineIterator()
533 mLines
= gDummyLines
;
536 mRightToLeft
= PR_FALSE
;
539 nsLineIterator::~nsLineIterator()
541 if (mLines
!= gDummyLines
) {
546 NS_IMPL_ISUPPORTS2(nsLineIterator
, nsILineIterator
, nsILineIteratorNavigator
)
549 nsLineIterator::Init(nsLineList
& aLines
, PRBool aRightToLeft
)
551 mRightToLeft
= aRightToLeft
;
554 PRInt32 numLines
= aLines
.size();
556 // Use gDummyLines so that we don't need null pointer checks in
557 // the accessor methods
558 mLines
= gDummyLines
;
562 // Make a linear array of the lines
563 mLines
= new nsLineBox
*[numLines
];
565 // Use gDummyLines so that we don't need null pointer checks in
566 // the accessor methods
567 mLines
= gDummyLines
;
568 return NS_ERROR_OUT_OF_MEMORY
;
570 nsLineBox
** lp
= mLines
;
571 for (nsLineList::iterator line
= aLines
.begin(), line_end
= aLines
.end() ;
577 mNumLines
= numLines
;
582 nsLineIterator::GetNumLines(PRInt32
* aResult
)
584 NS_PRECONDITION(aResult
, "null OUT ptr");
586 return NS_ERROR_NULL_POINTER
;
588 *aResult
= mNumLines
;
593 nsLineIterator::GetDirection(PRBool
* aIsRightToLeft
)
595 NS_PRECONDITION(aIsRightToLeft
, "null OUT ptr");
596 if (!aIsRightToLeft
) {
597 return NS_ERROR_NULL_POINTER
;
599 *aIsRightToLeft
= mRightToLeft
;
604 nsLineIterator::GetLine(PRInt32 aLineNumber
,
605 nsIFrame
** aFirstFrameOnLine
,
606 PRInt32
* aNumFramesOnLine
,
608 PRUint32
* aLineFlags
)
610 NS_ENSURE_ARG_POINTER(aFirstFrameOnLine
);
611 NS_ENSURE_ARG_POINTER(aNumFramesOnLine
);
612 NS_ENSURE_ARG_POINTER(aLineFlags
);
614 if ((aLineNumber
< 0) || (aLineNumber
>= mNumLines
)) {
615 *aFirstFrameOnLine
= nsnull
;
616 *aNumFramesOnLine
= 0;
617 aLineBounds
.SetRect(0, 0, 0, 0);
620 nsLineBox
* line
= mLines
[aLineNumber
];
621 *aFirstFrameOnLine
= line
->mFirstChild
;
622 *aNumFramesOnLine
= line
->GetChildCount();
623 aLineBounds
= line
->mBounds
;
626 if (line
->IsBlock()) {
627 flags
|= NS_LINE_FLAG_IS_BLOCK
;
630 if (line
->HasBreakAfter())
631 flags
|= NS_LINE_FLAG_ENDS_IN_BREAK
;
639 nsLineIterator::FindLineContaining(nsIFrame
* aFrame
,
640 PRInt32
* aLineNumberResult
)
642 nsLineBox
* line
= mLines
[0];
643 PRInt32 lineNumber
= 0;
644 while (lineNumber
!= mNumLines
) {
645 if (line
->Contains(aFrame
)) {
646 *aLineNumberResult
= lineNumber
;
649 line
= mLines
[++lineNumber
];
651 *aLineNumberResult
= -1;
656 nsLineIterator::FindLineAt(nscoord aY
,
657 PRInt32
* aLineNumberResult
)
659 nsLineBox
* line
= mLines
[0];
660 if (!line
|| (aY
< line
->mBounds
.y
)) {
661 *aLineNumberResult
= -1;
664 PRInt32 lineNumber
= 0;
665 while (lineNumber
!= mNumLines
) {
666 if ((aY
>= line
->mBounds
.y
) && (aY
< line
->mBounds
.YMost())) {
667 *aLineNumberResult
= lineNumber
;
670 line
= mLines
[++lineNumber
];
672 *aLineNumberResult
= mNumLines
;
678 nsLineIterator::CheckLineOrder(PRInt32 aLine
,
679 PRBool
*aIsReordered
,
680 nsIFrame
**aFirstVisual
,
681 nsIFrame
**aLastVisual
)
683 NS_ASSERTION (aLine
>= 0 && aLine
< mNumLines
, "aLine out of range!");
684 nsLineBox
* line
= mLines
[aLine
];
686 if (!line
->mFirstChild
) { // empty line
687 *aIsReordered
= PR_FALSE
;
688 *aFirstVisual
= nsnull
;
689 *aLastVisual
= nsnull
;
693 nsPresContext
* presContext
= line
->mFirstChild
->PresContext();
695 nsBidiPresUtils
* bidiUtils
= presContext
->GetBidiUtils();
697 nsIFrame
* leftmostFrame
;
698 nsIFrame
* rightmostFrame
;
699 *aIsReordered
= bidiUtils
->CheckLineOrder(line
->mFirstChild
, line
->GetChildCount(), &leftmostFrame
, &rightmostFrame
);
701 // map leftmost/rightmost to first/last according to paragraph direction
702 *aFirstVisual
= mRightToLeft
? rightmostFrame
: leftmostFrame
;
703 *aLastVisual
= mRightToLeft
? leftmostFrame
: rightmostFrame
;
710 nsLineIterator::FindFrameAt(PRInt32 aLineNumber
,
712 nsIFrame
** aFrameFound
,
713 PRBool
* aXIsBeforeFirstFrame
,
714 PRBool
* aXIsAfterLastFrame
)
716 NS_PRECONDITION(aFrameFound
&& aXIsBeforeFirstFrame
&& aXIsAfterLastFrame
,
718 if (!aFrameFound
|| !aXIsBeforeFirstFrame
|| !aXIsAfterLastFrame
) {
719 return NS_ERROR_NULL_POINTER
;
721 if ((aLineNumber
< 0) || (aLineNumber
>= mNumLines
)) {
722 return NS_ERROR_INVALID_ARG
;
725 nsLineBox
* line
= mLines
[aLineNumber
];
727 *aFrameFound
= nsnull
;
728 *aXIsBeforeFirstFrame
= PR_TRUE
;
729 *aXIsAfterLastFrame
= PR_FALSE
;
733 if (line
->mBounds
.width
== 0 && line
->mBounds
.height
== 0)
734 return NS_ERROR_FAILURE
;
736 nsIFrame
* frame
= line
->mFirstChild
;
737 nsIFrame
* closestFromLeft
= nsnull
;
738 nsIFrame
* closestFromRight
= nsnull
;
739 PRInt32 n
= line
->GetChildCount();
741 nsRect rect
= frame
->GetRect();
742 if (rect
.width
> 0) {
743 // If aX is inside this frame - this is it
744 if (rect
.x
<= aX
&& rect
.XMost() > aX
) {
745 closestFromLeft
= closestFromRight
= frame
;
749 if (!closestFromLeft
||
750 rect
.XMost() > closestFromLeft
->GetRect().XMost())
751 closestFromLeft
= frame
;
754 if (!closestFromRight
||
755 rect
.x
< closestFromRight
->GetRect().x
)
756 closestFromRight
= frame
;
759 frame
= frame
->GetNextSibling();
761 if (!closestFromLeft
&& !closestFromRight
) {
762 // All frames were zero-width. Just take the first one.
763 closestFromLeft
= closestFromRight
= line
->mFirstChild
;
765 *aXIsBeforeFirstFrame
= mRightToLeft
? !closestFromRight
: !closestFromLeft
;
766 *aXIsAfterLastFrame
= mRightToLeft
? !closestFromLeft
: !closestFromRight
;
767 if (closestFromLeft
== closestFromRight
) {
768 *aFrameFound
= closestFromLeft
;
770 else if (!closestFromLeft
) {
771 *aFrameFound
= closestFromRight
;
773 else if (!closestFromRight
) {
774 *aFrameFound
= closestFromLeft
;
776 else { // we're between two frames
777 nscoord delta
= closestFromRight
->GetRect().x
- closestFromLeft
->GetRect().XMost();
778 if (aX
< closestFromLeft
->GetRect().XMost() + delta
/2)
779 *aFrameFound
= closestFromLeft
;
781 *aFrameFound
= closestFromRight
;
787 nsLineIterator::GetNextSiblingOnLine(nsIFrame
*& aFrame
, PRInt32 aLineNumber
)
789 aFrame
= aFrame
->GetNextSibling();
793 //----------------------------------------------------------------------
795 #ifdef NS_BUILD_REFCNT_LOGGING
796 nsFloatCacheList::nsFloatCacheList() :
799 MOZ_COUNT_CTOR(nsFloatCacheList
);
803 nsFloatCacheList::~nsFloatCacheList()
806 MOZ_COUNT_DTOR(nsFloatCacheList
);
810 nsFloatCacheList::DeleteAll()
812 nsFloatCache
* c
= mHead
;
814 nsFloatCache
* next
= c
->Next();
822 nsFloatCacheList::Tail() const
824 nsFloatCache
* fc
= mHead
;
835 nsFloatCacheList::Append(nsFloatCacheFreeList
& aList
)
837 NS_PRECONDITION(aList
.NotEmpty(), "Appending empty list will fail");
839 nsFloatCache
* tail
= Tail();
841 NS_ASSERTION(!tail
->mNext
, "Bogus!");
842 tail
->mNext
= aList
.mHead
;
845 NS_ASSERTION(!mHead
, "Bogus!");
848 aList
.mHead
= nsnull
;
849 aList
.mTail
= nsnull
;
853 nsFloatCacheList::Find(nsIFrame
* aOutOfFlowFrame
)
855 nsFloatCache
* fc
= mHead
;
857 if (fc
->mPlaceholder
->GetOutOfFlowFrame() == aOutOfFlowFrame
) {
866 nsFloatCacheList::RemoveAndReturnPrev(nsFloatCache
* aElement
)
868 nsFloatCache
* fc
= mHead
;
869 nsFloatCache
* prev
= nsnull
;
871 if (fc
== aElement
) {
873 prev
->mNext
= fc
->mNext
;
885 //----------------------------------------------------------------------
887 #ifdef NS_BUILD_REFCNT_LOGGING
888 nsFloatCacheFreeList::nsFloatCacheFreeList() :
891 MOZ_COUNT_CTOR(nsFloatCacheFreeList
);
894 nsFloatCacheFreeList::~nsFloatCacheFreeList()
896 MOZ_COUNT_DTOR(nsFloatCacheFreeList
);
901 nsFloatCacheFreeList::Append(nsFloatCacheList
& aList
)
903 NS_PRECONDITION(aList
.NotEmpty(), "Appending empty list will fail");
906 NS_ASSERTION(!mTail
->mNext
, "Bogus");
907 mTail
->mNext
= aList
.mHead
;
910 NS_ASSERTION(!mHead
, "Bogus");
913 mTail
= aList
.Tail();
914 aList
.mHead
= nsnull
;
918 nsFloatCacheFreeList::Remove(nsFloatCache
* aElement
)
920 nsFloatCache
* prev
= nsFloatCacheList::RemoveAndReturnPrev(aElement
);
921 if (mTail
== aElement
) {
927 nsFloatCacheFreeList::DeleteAll()
929 nsFloatCacheList::DeleteAll();
934 nsFloatCacheFreeList::Alloc()
936 nsFloatCache
* fc
= mHead
;
938 if (mHead
== mTail
) {
939 mHead
= mTail
= nsnull
;
947 fc
= new nsFloatCache();
953 nsFloatCacheFreeList::Append(nsFloatCache
* aFloat
)
955 NS_ASSERTION(!aFloat
->mNext
, "Bogus!");
956 aFloat
->mNext
= nsnull
;
958 NS_ASSERTION(!mTail
->mNext
, "Bogus!");
959 mTail
->mNext
= aFloat
;
963 NS_ASSERTION(!mHead
, "Bogus!");
964 mHead
= mTail
= aFloat
;
968 //----------------------------------------------------------------------
970 nsFloatCache::nsFloatCache()
971 : mPlaceholder(nsnull
),
974 MOZ_COUNT_CTOR(nsFloatCache
);
977 #ifdef NS_BUILD_REFCNT_LOGGING
978 nsFloatCache::~nsFloatCache()
980 MOZ_COUNT_DTOR(nsFloatCache
);