1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 // vim:cindent:ts=2:et:sw=2:
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 /* representation of one line within a block frame, a CSS line box */
10 #define nsLineBox_h___
12 #include "mozilla/Attributes.h"
13 #include "mozilla/Likely.h"
15 #include "nsILineIterator.h"
21 class nsFloatCacheList
;
22 class nsFloatCacheFreeList
;
24 // State cached after reflowing a float. This state is used during
25 // incremental reflow when we avoid reflowing a float.
29 #ifdef NS_BUILD_REFCNT_LOGGING
35 nsFloatCache
* Next() const { return mNext
; }
37 nsIFrame
* mFloat
; // floating frame
42 friend class nsFloatCacheList
;
43 friend class nsFloatCacheFreeList
;
46 //----------------------------------------
48 class nsFloatCacheList
{
50 #ifdef NS_BUILD_REFCNT_LOGGING
53 nsFloatCacheList() : mHead(nullptr) { }
57 bool IsEmpty() const {
58 return nullptr == mHead
;
61 bool NotEmpty() const {
62 return nullptr != mHead
;
65 nsFloatCache
* Head() const {
69 nsFloatCache
* Tail() const;
73 nsFloatCache
* Find(nsIFrame
* aOutOfFlowFrame
);
75 // Remove a nsFloatCache from this list. Deleting this nsFloatCache
76 // becomes the caller's responsibility.
77 void Remove(nsFloatCache
* aElement
) { RemoveAndReturnPrev(aElement
); }
79 // Steal away aList's nsFloatCache objects and put them in this
80 // list. aList must not be empty.
81 void Append(nsFloatCacheFreeList
& aList
);
86 // Remove a nsFloatCache from this list. Deleting this nsFloatCache
87 // becomes the caller's responsibility. Returns the nsFloatCache that was
88 // before aElement, or nullptr if aElement was the first.
89 nsFloatCache
* RemoveAndReturnPrev(nsFloatCache
* aElement
);
91 friend class nsFloatCacheFreeList
;
94 //---------------------------------------
95 // Like nsFloatCacheList, but with fast access to the tail
97 class nsFloatCacheFreeList
: private nsFloatCacheList
{
99 #ifdef NS_BUILD_REFCNT_LOGGING
100 nsFloatCacheFreeList();
101 ~nsFloatCacheFreeList();
103 nsFloatCacheFreeList() : mTail(nullptr) { }
104 ~nsFloatCacheFreeList() { }
107 // Reimplement trivial functions
108 bool IsEmpty() const {
109 return nullptr == mHead
;
112 nsFloatCache
* Head() const {
116 nsFloatCache
* Tail() const {
120 bool NotEmpty() const {
121 return nullptr != mHead
;
126 // Steal away aList's nsFloatCache objects and put them on this
127 // free-list. aList must not be empty.
128 void Append(nsFloatCacheList
& aList
);
130 void Append(nsFloatCache
* aFloatCache
);
132 void Remove(nsFloatCache
* aElement
);
134 // Remove an nsFloatCache object from this list and return it, or create
135 // a new one if this one is empty; Set its mFloat to aFloat.
136 nsFloatCache
* Alloc(nsIFrame
* aFloat
);
141 friend class nsFloatCacheList
;
144 //----------------------------------------------------------------------
146 #define LINE_MAX_BREAK_TYPE ((1 << 4) - 1)
147 #define LINE_MAX_CHILD_COUNT INT32_MAX
150 * Function to create a line box and initialize it with a single frame.
151 * The allocation is infallible.
152 * If the frame was moved from another line then you're responsible
153 * for notifying that line using NoteFrameRemoved(). Alternatively,
154 * it's better to use the next function that does that for you in an
157 nsLineBox
* NS_NewLineBox(nsIPresShell
* aPresShell
, nsIFrame
* aFrame
,
160 * Function to create a line box and initialize it with aCount frames
161 * that are currently on aFromLine. The allocation is infallible.
163 nsLineBox
* NS_NewLineBox(nsIPresShell
* aPresShell
, nsLineBox
* aFromLine
,
164 nsIFrame
* aFrame
, int32_t aCount
);
168 // don't use the following names outside of this file. Instead, use
169 // nsLineList::iterator, etc. These are just here to allow them to
170 // be specified as parameters to methods of nsLineBox.
171 class nsLineList_iterator
;
172 class nsLineList_const_iterator
;
173 class nsLineList_reverse_iterator
;
174 class nsLineList_const_reverse_iterator
;
177 * Users must have the class that is to be part of the list inherit
178 * from nsLineLink. If they want to be efficient, it should be the
179 * first base class. (This was originally nsCLink in a templatized
180 * nsCList, but it's still useful separately.)
186 friend class nsLineList
;
187 friend class nsLineList_iterator
;
188 friend class nsLineList_reverse_iterator
;
189 friend class nsLineList_const_iterator
;
190 friend class nsLineList_const_reverse_iterator
;
193 nsLineLink
*_mNext
; // or head
194 nsLineLink
*_mPrev
; // or tail
200 * The nsLineBox class represents a horizontal line of frames. It contains
201 * enough state to support incremental reflow of the frames, event handling
202 * for the frames, and rendering of the frames.
204 class nsLineBox MOZ_FINAL
: public nsLineLink
{
206 nsLineBox(nsIFrame
* aFrame
, int32_t aCount
, bool aIsBlock
);
209 // Overloaded new operator. Uses an arena (which comes from the presShell)
210 // to perform the allocation.
211 void* operator new(size_t sz
, nsIPresShell
* aPresShell
) CPP_THROW_NEW
;
212 void operator delete(void* aPtr
, size_t sz
) = delete;
215 // Use these functions to allocate and destroy line boxes
216 friend nsLineBox
* NS_NewLineBox(nsIPresShell
* aPresShell
, nsIFrame
* aFrame
,
218 friend nsLineBox
* NS_NewLineBox(nsIPresShell
* aPresShell
, nsLineBox
* aFromLine
,
219 nsIFrame
* aFrame
, int32_t aCount
);
220 void Destroy(nsIPresShell
* aPresShell
);
223 bool IsBlock() const {
224 return mFlags
.mBlock
;
226 bool IsInline() const {
227 return 0 == mFlags
.mBlock
;
237 bool IsDirty() const {
238 return mFlags
.mDirty
;
241 // mPreviousMarginDirty bit
242 void MarkPreviousMarginDirty() {
243 mFlags
.mPreviousMarginDirty
= 1;
245 void ClearPreviousMarginDirty() {
246 mFlags
.mPreviousMarginDirty
= 0;
248 bool IsPreviousMarginDirty() const {
249 return mFlags
.mPreviousMarginDirty
;
253 void SetHasClearance() {
254 mFlags
.mHasClearance
= 1;
256 void ClearHasClearance() {
257 mFlags
.mHasClearance
= 0;
259 bool HasClearance() const {
260 return mFlags
.mHasClearance
;
263 // mImpactedByFloat bit
264 void SetLineIsImpactedByFloat(bool aValue
) {
265 mFlags
.mImpactedByFloat
= aValue
;
267 bool IsImpactedByFloat() const {
268 return mFlags
.mImpactedByFloat
;
272 void SetLineWrapped(bool aOn
) {
273 mFlags
.mLineWrapped
= aOn
;
275 bool IsLineWrapped() const {
276 return mFlags
.mLineWrapped
;
279 // mInvalidateTextRuns bit
280 void SetInvalidateTextRuns(bool aOn
) {
281 mFlags
.mInvalidateTextRuns
= aOn
;
283 bool GetInvalidateTextRuns() const {
284 return mFlags
.mInvalidateTextRuns
;
287 // mResizeReflowOptimizationDisabled bit
288 void DisableResizeReflowOptimization() {
289 mFlags
.mResizeReflowOptimizationDisabled
= true;
291 void EnableResizeReflowOptimization() {
292 mFlags
.mResizeReflowOptimizationDisabled
= false;
294 bool ResizeReflowOptimizationDisabled() const {
295 return mFlags
.mResizeReflowOptimizationDisabled
;
299 void SetHasBullet() {
300 mFlags
.mHasBullet
= true;
301 InvalidateCachedIsEmpty();
303 void ClearHasBullet() {
304 mFlags
.mHasBullet
= false;
305 InvalidateCachedIsEmpty();
307 bool HasBullet() const {
308 return mFlags
.mHasBullet
;
311 // mHadFloatPushed bit
312 void SetHadFloatPushed() {
313 mFlags
.mHadFloatPushed
= true;
315 void ClearHadFloatPushed() {
316 mFlags
.mHadFloatPushed
= false;
318 bool HadFloatPushed() const {
319 return mFlags
.mHadFloatPushed
;
323 // Add a hash table for fast lookup when the line has more frames than this.
324 static const uint32_t kMinChildCountForHashtable
= 200;
327 * Take ownership of aFromLine's hash table and remove the frames that
328 * stay on aFromLine from it, i.e. aFromLineNewCount frames starting with
329 * mFirstChild. This method is used to optimize moving a large number
330 * of frames from one line to the next.
332 void StealHashTableFrom(nsLineBox
* aFromLine
, uint32_t aFromLineNewCount
);
335 * Does the equivalent of this->NoteFrameAdded and aFromLine->NoteFrameRemoved
336 * for each frame on this line, but in a optimized way.
338 void NoteFramesMovedFrom(nsLineBox
* aFromLine
);
340 void SwitchToHashtable()
342 MOZ_ASSERT(!mFlags
.mHasHashedFrames
);
343 uint32_t count
= GetChildCount();
344 mFlags
.mHasHashedFrames
= 1;
345 uint32_t minLength
= std::max(kMinChildCountForHashtable
,
346 uint32_t(PL_DHASH_DEFAULT_INITIAL_LENGTH
));
347 mFrames
= new nsTHashtable
< nsPtrHashKey
<nsIFrame
> >(std::max(count
, minLength
));
348 for (nsIFrame
* f
= mFirstChild
; count
-- > 0; f
= f
->GetNextSibling()) {
349 mFrames
->PutEntry(f
);
352 void SwitchToCounter() {
353 MOZ_ASSERT(mFlags
.mHasHashedFrames
);
354 uint32_t count
= GetChildCount();
356 mFlags
.mHasHashedFrames
= 0;
361 int32_t GetChildCount() const {
362 return MOZ_UNLIKELY(mFlags
.mHasHashedFrames
) ? mFrames
->Count() : mChildCount
;
366 * Register that aFrame is now on this line.
368 void NoteFrameAdded(nsIFrame
* aFrame
) {
369 if (MOZ_UNLIKELY(mFlags
.mHasHashedFrames
)) {
370 mFrames
->PutEntry(aFrame
);
372 if (++mChildCount
>= kMinChildCountForHashtable
) {
379 * Register that aFrame is not on this line anymore.
381 void NoteFrameRemoved(nsIFrame
* aFrame
) {
382 MOZ_ASSERT(GetChildCount() > 0);
383 if (MOZ_UNLIKELY(mFlags
.mHasHashedFrames
)) {
384 mFrames
->RemoveEntry(aFrame
);
385 if (mFrames
->Count() < kMinChildCountForHashtable
) {
394 // Break information is applied *before* the line if the line is a block,
395 // or *after* the line if the line is an inline. Confusing, I know, but
396 // using different names should help.
397 bool HasBreakBefore() const {
398 return IsBlock() && NS_STYLE_CLEAR_NONE
!= mFlags
.mBreakType
;
400 void SetBreakTypeBefore(uint8_t aBreakType
) {
401 NS_ASSERTION(IsBlock(), "Only blocks have break-before");
402 NS_ASSERTION(aBreakType
== NS_STYLE_CLEAR_NONE
||
403 aBreakType
== NS_STYLE_CLEAR_LEFT
||
404 aBreakType
== NS_STYLE_CLEAR_RIGHT
||
405 aBreakType
== NS_STYLE_CLEAR_BOTH
,
406 "Only float break types are allowed before a line");
407 mFlags
.mBreakType
= aBreakType
;
409 uint8_t GetBreakTypeBefore() const {
410 return IsBlock() ? mFlags
.mBreakType
: NS_STYLE_CLEAR_NONE
;
413 bool HasBreakAfter() const {
414 return !IsBlock() && NS_STYLE_CLEAR_NONE
!= mFlags
.mBreakType
;
416 void SetBreakTypeAfter(uint8_t aBreakType
) {
417 NS_ASSERTION(!IsBlock(), "Only inlines have break-after");
418 NS_ASSERTION(aBreakType
<= LINE_MAX_BREAK_TYPE
, "bad break type");
419 mFlags
.mBreakType
= aBreakType
;
421 bool HasFloatBreakAfter() const {
422 return !IsBlock() && (NS_STYLE_CLEAR_LEFT
== mFlags
.mBreakType
||
423 NS_STYLE_CLEAR_RIGHT
== mFlags
.mBreakType
||
424 NS_STYLE_CLEAR_BOTH
== mFlags
.mBreakType
);
426 uint8_t GetBreakTypeAfter() const {
427 return !IsBlock() ? mFlags
.mBreakType
: NS_STYLE_CLEAR_NONE
;
430 // mCarriedOutBEndMargin value
431 nsCollapsingMargin
GetCarriedOutBEndMargin() const;
432 // Returns true if the margin changed
433 bool SetCarriedOutBEndMargin(nsCollapsingMargin aValue
);
436 bool HasFloats() const {
437 return (IsInline() && mInlineData
) && mInlineData
->mFloats
.NotEmpty();
439 nsFloatCache
* GetFirstFloat();
440 void FreeFloats(nsFloatCacheFreeList
& aFreeList
);
441 void AppendFloats(nsFloatCacheFreeList
& aFreeList
);
442 bool RemoveFloat(nsIFrame
* aFrame
);
444 // Combined area is the area of the line that should influence the
445 // overflow area of its parent block. The combined area should be
446 // used for painting-related things, but should never be used for
447 // layout (except for handling of 'overflow').
448 void SetOverflowAreas(const nsOverflowAreas
& aOverflowAreas
);
449 nsRect
GetOverflowArea(nsOverflowType aType
) {
450 return mData
? mData
->mOverflowAreas
.Overflow(aType
) : GetPhysicalBounds();
452 nsOverflowAreas
GetOverflowAreas() {
454 return mData
->mOverflowAreas
;
456 nsRect bounds
= GetPhysicalBounds();
457 return nsOverflowAreas(bounds
, bounds
);
459 nsRect
GetVisualOverflowArea()
460 { return GetOverflowArea(eVisualOverflow
); }
461 nsRect
GetScrollableOverflowArea()
462 { return GetOverflowArea(eScrollableOverflow
); }
464 void SlideBy(nscoord aDBCoord
, nscoord aContainerWidth
) {
465 NS_ASSERTION(aContainerWidth
== mContainerWidth
|| mContainerWidth
== -1,
466 "container width doesn't match");
467 mContainerWidth
= aContainerWidth
;
468 mBounds
.BStart(mWritingMode
) += aDBCoord
;
470 nsPoint physicalDelta
= mozilla::LogicalPoint(mWritingMode
, 0, aDBCoord
).
471 GetPhysicalPoint(mWritingMode
, 0);
472 NS_FOR_FRAME_OVERFLOW_TYPES(otype
) {
473 mData
->mOverflowAreas
.Overflow(otype
) += physicalDelta
;
478 // Container-width for the line is changing (and therefore if writing mode
479 // was vertical-rl, the line will move physically; this is like SlideBy,
480 // but it is the container width instead of the line's own logical coord
482 nscoord
UpdateContainerWidth(nscoord aNewContainerWidth
)
484 NS_ASSERTION(mContainerWidth
!= -1, "container width not set");
485 nscoord delta
= mContainerWidth
- aNewContainerWidth
;
486 mContainerWidth
= aNewContainerWidth
;
487 // this has a physical-coordinate effect only in vertical-rl mode
488 if (mWritingMode
.IsVerticalRL() && mData
) {
489 nsPoint physicalDelta
= mozilla::LogicalPoint(mWritingMode
, 0, delta
).
490 GetPhysicalPoint(mWritingMode
, 0);
491 NS_FOR_FRAME_OVERFLOW_TYPES(otype
) {
492 mData
->mOverflowAreas
.Overflow(otype
) += physicalDelta
;
498 void IndentBy(nscoord aDICoord
, nscoord aContainerWidth
) {
499 NS_ASSERTION(aContainerWidth
== mContainerWidth
|| mContainerWidth
== -1,
500 "container width doesn't match");
501 mContainerWidth
= aContainerWidth
;
502 mBounds
.IStart(mWritingMode
) += aDICoord
;
505 void ExpandBy(nscoord aDISize
, nscoord aContainerWidth
) {
506 NS_ASSERTION(aContainerWidth
== mContainerWidth
|| mContainerWidth
== -1,
507 "container width doesn't match");
508 mContainerWidth
= aContainerWidth
;
509 mBounds
.ISize(mWritingMode
) += aDISize
;
513 * The logical ascent (distance from block-start to baseline) of the
514 * linebox is the logical ascent of the anonymous inline box (for
515 * which we don't actually create a frame) that wraps all the
516 * consecutive inline children of a block.
518 * This is currently unused for block lines.
520 nscoord
GetLogicalAscent() const { return mAscent
; }
521 void SetLogicalAscent(nscoord aAscent
) { mAscent
= aAscent
; }
523 nscoord
BStart() const {
524 return mBounds
.BStart(mWritingMode
);
526 nscoord
BSize() const {
527 return mBounds
.BSize(mWritingMode
);
529 nscoord
BEnd() const {
530 return mBounds
.BEnd(mWritingMode
);
532 nscoord
IStart() const {
533 return mBounds
.IStart(mWritingMode
);
535 nscoord
ISize() const {
536 return mBounds
.ISize(mWritingMode
);
538 nscoord
IEnd() const {
539 return mBounds
.IEnd(mWritingMode
);
541 void SetBoundsEmpty() {
542 mBounds
.IStart(mWritingMode
) = 0;
543 mBounds
.ISize(mWritingMode
) = 0;
544 mBounds
.BStart(mWritingMode
) = 0;
545 mBounds
.BSize(mWritingMode
) = 0;
548 static void DeleteLineList(nsPresContext
* aPresContext
, nsLineList
& aLines
,
549 nsIFrame
* aDestructRoot
, nsFrameList
* aFrames
);
551 // search from end to beginning of [aBegin, aEnd)
552 // Returns true if it found the line and false if not.
553 // Moves aEnd as it searches so that aEnd points to the resulting line.
554 // aLastFrameBeforeEnd is the last frame before aEnd (so if aEnd is
555 // the end of the line list, it's just the last frame in the frame
557 static bool RFindLineContaining(nsIFrame
* aFrame
,
558 const nsLineList_iterator
& aBegin
,
559 nsLineList_iterator
& aEnd
,
560 nsIFrame
* aLastFrameBeforeEnd
,
561 int32_t* aFrameIndexInLine
);
563 #ifdef DEBUG_FRAME_DUMP
564 char* StateToString(char* aBuf
, int32_t aBufSize
) const;
566 void List(FILE* out
, int32_t aIndent
, uint32_t aFlags
= 0) const;
567 void List(FILE* out
= stderr
, const char* aPrefix
= "", uint32_t aFlags
= 0) const;
568 nsIFrame
* LastChild() const;
572 int32_t IndexOf(nsIFrame
* aFrame
) const;
575 bool Contains(nsIFrame
* aFrame
) const {
576 return MOZ_UNLIKELY(mFlags
.mHasHashedFrames
) ? mFrames
->Contains(aFrame
)
577 : IndexOf(aFrame
) >= 0;
580 // whether the line box is "logically" empty (just like nsIFrame::IsEmpty)
581 bool IsEmpty() const;
583 // Call this only while in Reflow() for the block the line belongs
584 // to, only between reflowing the line (or sliding it, if we skip
585 // reflowing it) and the end of reflowing the block.
586 bool CachedIsEmpty();
588 void InvalidateCachedIsEmpty() {
589 mFlags
.mEmptyCacheValid
= false;
592 // For debugging purposes
593 bool IsValidCachedIsEmpty() {
594 return mFlags
.mEmptyCacheValid
;
598 static int32_t GetCtorCount();
601 nsIFrame
* mFirstChild
;
603 mozilla::WritingMode mWritingMode
;
605 // Physical width. Use only for physical <-> logical coordinate conversion.
606 nscoord mContainerWidth
;
609 mozilla::LogicalRect mBounds
;
612 const mozilla::LogicalRect
& GetBounds() { return mBounds
; }
613 nsRect
GetPhysicalBounds() const
615 if (mBounds
.IsAllZero()) {
616 return nsRect(0, 0, 0, 0);
619 NS_ASSERTION(mContainerWidth
!= -1, "mContainerWidth not initialized");
620 return mBounds
.GetPhysicalRect(mWritingMode
, mContainerWidth
);
622 void SetBounds(mozilla::WritingMode aWritingMode
,
623 nscoord aIStart
, nscoord aBStart
,
624 nscoord aISize
, nscoord aBSize
,
625 nscoord aContainerWidth
)
627 mWritingMode
= aWritingMode
;
628 mContainerWidth
= aContainerWidth
;
629 mBounds
= mozilla::LogicalRect(aWritingMode
, aIStart
, aBStart
,
632 void SetBounds(mozilla::WritingMode aWritingMode
,
633 nsRect aRect
, nscoord aContainerWidth
)
635 mWritingMode
= aWritingMode
;
636 mContainerWidth
= aContainerWidth
;
637 mBounds
= mozilla::LogicalRect(aWritingMode
, aRect
, aContainerWidth
);
640 // mFlags.mHasHashedFrames says which one to use
642 nsTHashtable
< nsPtrHashKey
<nsIFrame
> >* mFrames
;
643 uint32_t mChildCount
;
648 uint32_t mPreviousMarginDirty
: 1;
649 uint32_t mHasClearance
: 1;
651 uint32_t mImpactedByFloat
: 1;
652 uint32_t mLineWrapped
: 1;
653 uint32_t mInvalidateTextRuns
: 1;
654 uint32_t mResizeReflowOptimizationDisabled
: 1; // default 0 = means that the opt potentially applies to this line. 1 = never skip reflowing this line for a resize reflow
655 uint32_t mEmptyCacheValid
: 1;
656 uint32_t mEmptyCacheState
: 1;
657 // mHasBullet indicates that this is an inline line whose block's
658 // bullet is adjacent to this line and non-empty.
659 uint32_t mHasBullet
: 1;
660 // Indicates that this line *may* have a placeholder for a float
661 // that was pushed to a later column or page.
662 uint32_t mHadFloatPushed
: 1;
663 uint32_t mHasHashedFrames
: 1;
664 uint32_t mBreakType
: 4;
668 explicit ExtraData(const nsRect
& aBounds
) : mOverflowAreas(aBounds
, aBounds
) {
670 nsOverflowAreas mOverflowAreas
;
673 struct ExtraBlockData
: public ExtraData
{
674 explicit ExtraBlockData(const nsRect
& aBounds
)
675 : ExtraData(aBounds
),
676 mCarriedOutBEndMargin()
679 nsCollapsingMargin mCarriedOutBEndMargin
;
682 struct ExtraInlineData
: public ExtraData
{
683 explicit ExtraInlineData(const nsRect
& aBounds
) : ExtraData(aBounds
) {
685 nsFloatCacheList mFloats
;
689 nscoord mAscent
; // see |SetAscent| / |GetAscent|
697 ExtraBlockData
* mBlockData
;
698 ExtraInlineData
* mInlineData
;
702 void MaybeFreeData();
706 * A linked list type where the items in the list must inherit from
707 * a link type to fuse allocations.
709 * API heavily based on the |list| class in the C++ standard.
712 class nsLineList_iterator
{
714 friend class nsLineList
;
715 friend class nsLineList_reverse_iterator
;
716 friend class nsLineList_const_iterator
;
717 friend class nsLineList_const_reverse_iterator
;
719 typedef nsLineList_iterator iterator_self_type
;
720 typedef nsLineList_reverse_iterator iterator_reverse_type
;
722 typedef nsLineBox
& reference
;
723 typedef const nsLineBox
& const_reference
;
725 typedef nsLineBox
* pointer
;
726 typedef const nsLineBox
* const_pointer
;
728 typedef uint32_t size_type
;
729 typedef int32_t difference_type
;
731 typedef nsLineLink link_type
;
734 nsLineList_iterator() { memset(&mCurrent
, 0xcd, sizeof(mCurrent
)); }
736 // Auto generated default constructor OK.
738 // Auto generated copy-constructor OK.
740 inline iterator_self_type
&
741 operator=(const iterator_self_type
& aOther
);
742 inline iterator_self_type
&
743 operator=(const iterator_reverse_type
& aOther
);
745 iterator_self_type
& operator++()
747 mCurrent
= mCurrent
->_mNext
;
751 iterator_self_type
operator++(int)
753 iterator_self_type
rv(*this);
754 mCurrent
= mCurrent
->_mNext
;
758 iterator_self_type
& operator--()
760 mCurrent
= mCurrent
->_mPrev
;
764 iterator_self_type
operator--(int)
766 iterator_self_type
rv(*this);
767 mCurrent
= mCurrent
->_mPrev
;
771 reference
operator*()
773 NS_ABORT_IF_FALSE(mCurrent
!= mListLink
, "running past end");
774 return *static_cast<pointer
>(mCurrent
);
779 NS_ABORT_IF_FALSE(mCurrent
!= mListLink
, "running past end");
780 return static_cast<pointer
>(mCurrent
);
785 NS_ABORT_IF_FALSE(mCurrent
!= mListLink
, "running past end");
786 return static_cast<pointer
>(mCurrent
);
791 NS_ABORT_IF_FALSE(mCurrent
!= mListLink
, "running past end");
792 return static_cast<pointer
>(mCurrent
);
795 const_reference
operator*() const
797 NS_ABORT_IF_FALSE(mCurrent
!= mListLink
, "running past end");
798 return *static_cast<const_pointer
>(mCurrent
);
801 const_pointer
operator->() const
803 NS_ABORT_IF_FALSE(mCurrent
!= mListLink
, "running past end");
804 return static_cast<const_pointer
>(mCurrent
);
808 operator const_pointer() const
810 NS_ABORT_IF_FALSE(mCurrent
!= mListLink
, "running past end");
811 return static_cast<const_pointer
>(mCurrent
);
813 #endif /* !__MWERKS__ */
815 iterator_self_type
next()
817 iterator_self_type
copy(*this);
821 const iterator_self_type
next() const
823 iterator_self_type
copy(*this);
827 iterator_self_type
prev()
829 iterator_self_type
copy(*this);
833 const iterator_self_type
prev() const
835 iterator_self_type
copy(*this);
839 // Passing by value rather than by reference and reference to const
840 // to keep AIX happy.
841 bool operator==(const iterator_self_type aOther
) const
843 NS_ABORT_IF_FALSE(mListLink
== aOther
.mListLink
, "comparing iterators over different lists");
844 return mCurrent
== aOther
.mCurrent
;
846 bool operator!=(const iterator_self_type aOther
) const
848 NS_ABORT_IF_FALSE(mListLink
== aOther
.mListLink
, "comparing iterators over different lists");
849 return mCurrent
!= aOther
.mCurrent
;
851 bool operator==(const iterator_self_type aOther
)
853 NS_ABORT_IF_FALSE(mListLink
== aOther
.mListLink
, "comparing iterators over different lists");
854 return mCurrent
== aOther
.mCurrent
;
856 bool operator!=(const iterator_self_type aOther
)
858 NS_ABORT_IF_FALSE(mListLink
== aOther
.mListLink
, "comparing iterators over different lists");
859 return mCurrent
!= aOther
.mCurrent
;
865 link_type
*mListLink
; // the list's link, i.e., the end
869 class nsLineList_reverse_iterator
{
873 friend class nsLineList
;
874 friend class nsLineList_iterator
;
875 friend class nsLineList_const_iterator
;
876 friend class nsLineList_const_reverse_iterator
;
878 typedef nsLineList_reverse_iterator iterator_self_type
;
879 typedef nsLineList_iterator iterator_reverse_type
;
881 typedef nsLineBox
& reference
;
882 typedef const nsLineBox
& const_reference
;
884 typedef nsLineBox
* pointer
;
885 typedef const nsLineBox
* const_pointer
;
887 typedef uint32_t size_type
;
888 typedef int32_t difference_type
;
890 typedef nsLineLink link_type
;
893 nsLineList_reverse_iterator() { memset(&mCurrent
, 0xcd, sizeof(mCurrent
)); }
895 // Auto generated default constructor OK.
897 // Auto generated copy-constructor OK.
899 inline iterator_self_type
&
900 operator=(const iterator_reverse_type
& aOther
);
901 inline iterator_self_type
&
902 operator=(const iterator_self_type
& aOther
);
904 iterator_self_type
& operator++()
906 mCurrent
= mCurrent
->_mPrev
;
910 iterator_self_type
operator++(int)
912 iterator_self_type
rv(*this);
913 mCurrent
= mCurrent
->_mPrev
;
917 iterator_self_type
& operator--()
919 mCurrent
= mCurrent
->_mNext
;
923 iterator_self_type
operator--(int)
925 iterator_self_type
rv(*this);
926 mCurrent
= mCurrent
->_mNext
;
930 reference
operator*()
932 NS_ABORT_IF_FALSE(mCurrent
!= mListLink
, "running past end");
933 return *static_cast<pointer
>(mCurrent
);
938 NS_ABORT_IF_FALSE(mCurrent
!= mListLink
, "running past end");
939 return static_cast<pointer
>(mCurrent
);
944 NS_ABORT_IF_FALSE(mCurrent
!= mListLink
, "running past end");
945 return static_cast<pointer
>(mCurrent
);
950 NS_ABORT_IF_FALSE(mCurrent
!= mListLink
, "running past end");
951 return static_cast<pointer
>(mCurrent
);
954 const_reference
operator*() const
956 NS_ABORT_IF_FALSE(mCurrent
!= mListLink
, "running past end");
957 return *static_cast<const_pointer
>(mCurrent
);
960 const_pointer
operator->() const
962 NS_ABORT_IF_FALSE(mCurrent
!= mListLink
, "running past end");
963 return static_cast<const_pointer
>(mCurrent
);
967 operator const_pointer() const
969 NS_ABORT_IF_FALSE(mCurrent
!= mListLink
, "running past end");
970 return static_cast<const_pointer
>(mCurrent
);
972 #endif /* !__MWERKS__ */
974 // Passing by value rather than by reference and reference to const
975 // to keep AIX happy.
976 bool operator==(const iterator_self_type aOther
) const
978 NS_ASSERTION(mListLink
== aOther
.mListLink
, "comparing iterators over different lists");
979 return mCurrent
== aOther
.mCurrent
;
981 bool operator!=(const iterator_self_type aOther
) const
983 NS_ASSERTION(mListLink
== aOther
.mListLink
, "comparing iterators over different lists");
984 return mCurrent
!= aOther
.mCurrent
;
986 bool operator==(const iterator_self_type aOther
)
988 NS_ASSERTION(mListLink
== aOther
.mListLink
, "comparing iterators over different lists");
989 return mCurrent
== aOther
.mCurrent
;
991 bool operator!=(const iterator_self_type aOther
)
993 NS_ASSERTION(mListLink
== aOther
.mListLink
, "comparing iterators over different lists");
994 return mCurrent
!= aOther
.mCurrent
;
1000 link_type
*mListLink
; // the list's link, i.e., the end
1004 class nsLineList_const_iterator
{
1007 friend class nsLineList
;
1008 friend class nsLineList_iterator
;
1009 friend class nsLineList_reverse_iterator
;
1010 friend class nsLineList_const_reverse_iterator
;
1012 typedef nsLineList_const_iterator iterator_self_type
;
1013 typedef nsLineList_const_reverse_iterator iterator_reverse_type
;
1014 typedef nsLineList_iterator iterator_nonconst_type
;
1015 typedef nsLineList_reverse_iterator iterator_nonconst_reverse_type
;
1017 typedef nsLineBox
& reference
;
1018 typedef const nsLineBox
& const_reference
;
1020 typedef nsLineBox
* pointer
;
1021 typedef const nsLineBox
* const_pointer
;
1023 typedef uint32_t size_type
;
1024 typedef int32_t difference_type
;
1026 typedef nsLineLink link_type
;
1029 nsLineList_const_iterator() { memset(&mCurrent
, 0xcd, sizeof(mCurrent
)); }
1031 // Auto generated default constructor OK.
1033 // Auto generated copy-constructor OK.
1035 inline iterator_self_type
&
1036 operator=(const iterator_nonconst_type
& aOther
);
1037 inline iterator_self_type
&
1038 operator=(const iterator_nonconst_reverse_type
& aOther
);
1039 inline iterator_self_type
&
1040 operator=(const iterator_self_type
& aOther
);
1041 inline iterator_self_type
&
1042 operator=(const iterator_reverse_type
& aOther
);
1044 iterator_self_type
& operator++()
1046 mCurrent
= mCurrent
->_mNext
;
1050 iterator_self_type
operator++(int)
1052 iterator_self_type
rv(*this);
1053 mCurrent
= mCurrent
->_mNext
;
1057 iterator_self_type
& operator--()
1059 mCurrent
= mCurrent
->_mPrev
;
1063 iterator_self_type
operator--(int)
1065 iterator_self_type
rv(*this);
1066 mCurrent
= mCurrent
->_mPrev
;
1070 const_reference
operator*() const
1072 NS_ABORT_IF_FALSE(mCurrent
!= mListLink
, "running past end");
1073 return *static_cast<const_pointer
>(mCurrent
);
1076 const_pointer
operator->() const
1078 NS_ABORT_IF_FALSE(mCurrent
!= mListLink
, "running past end");
1079 return static_cast<const_pointer
>(mCurrent
);
1082 const_pointer
get() const
1084 NS_ABORT_IF_FALSE(mCurrent
!= mListLink
, "running past end");
1085 return static_cast<const_pointer
>(mCurrent
);
1089 operator const_pointer() const
1091 NS_ABORT_IF_FALSE(mCurrent
!= mListLink
, "running past end");
1092 return static_cast<const_pointer
>(mCurrent
);
1094 #endif /* !__MWERKS__ */
1096 const iterator_self_type
next() const
1098 iterator_self_type
copy(*this);
1102 const iterator_self_type
prev() const
1104 iterator_self_type
copy(*this);
1108 // Passing by value rather than by reference and reference to const
1109 // to keep AIX happy.
1110 bool operator==(const iterator_self_type aOther
) const
1112 NS_ASSERTION(mListLink
== aOther
.mListLink
, "comparing iterators over different lists");
1113 return mCurrent
== aOther
.mCurrent
;
1115 bool operator!=(const iterator_self_type aOther
) const
1117 NS_ASSERTION(mListLink
== aOther
.mListLink
, "comparing iterators over different lists");
1118 return mCurrent
!= aOther
.mCurrent
;
1120 bool operator==(const iterator_self_type aOther
)
1122 NS_ASSERTION(mListLink
== aOther
.mListLink
, "comparing iterators over different lists");
1123 return mCurrent
== aOther
.mCurrent
;
1125 bool operator!=(const iterator_self_type aOther
)
1127 NS_ASSERTION(mListLink
== aOther
.mListLink
, "comparing iterators over different lists");
1128 return mCurrent
!= aOther
.mCurrent
;
1132 const link_type
*mCurrent
;
1134 const link_type
*mListLink
; // the list's link, i.e., the end
1138 class nsLineList_const_reverse_iterator
{
1141 friend class nsLineList
;
1142 friend class nsLineList_iterator
;
1143 friend class nsLineList_reverse_iterator
;
1144 friend class nsLineList_const_iterator
;
1146 typedef nsLineList_const_reverse_iterator iterator_self_type
;
1147 typedef nsLineList_const_iterator iterator_reverse_type
;
1148 typedef nsLineList_iterator iterator_nonconst_reverse_type
;
1149 typedef nsLineList_reverse_iterator iterator_nonconst_type
;
1151 typedef nsLineBox
& reference
;
1152 typedef const nsLineBox
& const_reference
;
1154 typedef nsLineBox
* pointer
;
1155 typedef const nsLineBox
* const_pointer
;
1157 typedef uint32_t size_type
;
1158 typedef int32_t difference_type
;
1160 typedef nsLineLink link_type
;
1163 nsLineList_const_reverse_iterator() { memset(&mCurrent
, 0xcd, sizeof(mCurrent
)); }
1165 // Auto generated default constructor OK.
1167 // Auto generated copy-constructor OK.
1169 inline iterator_self_type
&
1170 operator=(const iterator_nonconst_type
& aOther
);
1171 inline iterator_self_type
&
1172 operator=(const iterator_nonconst_reverse_type
& aOther
);
1173 inline iterator_self_type
&
1174 operator=(const iterator_self_type
& aOther
);
1175 inline iterator_self_type
&
1176 operator=(const iterator_reverse_type
& aOther
);
1178 iterator_self_type
& operator++()
1180 mCurrent
= mCurrent
->_mPrev
;
1184 iterator_self_type
operator++(int)
1186 iterator_self_type
rv(*this);
1187 mCurrent
= mCurrent
->_mPrev
;
1191 iterator_self_type
& operator--()
1193 mCurrent
= mCurrent
->_mNext
;
1197 iterator_self_type
operator--(int)
1199 iterator_self_type
rv(*this);
1200 mCurrent
= mCurrent
->_mNext
;
1204 const_reference
operator*() const
1206 NS_ABORT_IF_FALSE(mCurrent
!= mListLink
, "running past end");
1207 return *static_cast<const_pointer
>(mCurrent
);
1210 const_pointer
operator->() const
1212 NS_ABORT_IF_FALSE(mCurrent
!= mListLink
, "running past end");
1213 return static_cast<const_pointer
>(mCurrent
);
1216 const_pointer
get() const
1218 NS_ABORT_IF_FALSE(mCurrent
!= mListLink
, "running past end");
1219 return static_cast<const_pointer
>(mCurrent
);
1223 operator const_pointer() const
1225 NS_ABORT_IF_FALSE(mCurrent
!= mListLink
, "running past end");
1226 return static_cast<const_pointer
>(mCurrent
);
1228 #endif /* !__MWERKS__ */
1230 // Passing by value rather than by reference and reference to const
1231 // to keep AIX happy.
1232 bool operator==(const iterator_self_type aOther
) const
1234 NS_ASSERTION(mListLink
== aOther
.mListLink
, "comparing iterators over different lists");
1235 return mCurrent
== aOther
.mCurrent
;
1237 bool operator!=(const iterator_self_type aOther
) const
1239 NS_ASSERTION(mListLink
== aOther
.mListLink
, "comparing iterators over different lists");
1240 return mCurrent
!= aOther
.mCurrent
;
1242 bool operator==(const iterator_self_type aOther
)
1244 NS_ASSERTION(mListLink
== aOther
.mListLink
, "comparing iterators over different lists");
1245 return mCurrent
== aOther
.mCurrent
;
1247 bool operator!=(const iterator_self_type aOther
)
1249 NS_ASSERTION(mListLink
== aOther
.mListLink
, "comparing iterators over different lists");
1250 return mCurrent
!= aOther
.mCurrent
;
1254 const link_type
*mCurrent
;
1256 const link_type
*mListLink
; // the list's link, i.e., the end
1264 friend class nsLineList_iterator
;
1265 friend class nsLineList_reverse_iterator
;
1266 friend class nsLineList_const_iterator
;
1267 friend class nsLineList_const_reverse_iterator
;
1269 typedef uint32_t size_type
;
1270 typedef int32_t difference_type
;
1272 typedef nsLineLink link_type
;
1278 typedef nsLineList self_type
;
1280 typedef nsLineBox
& reference
;
1281 typedef const nsLineBox
& const_reference
;
1283 typedef nsLineBox
* pointer
;
1284 typedef const nsLineBox
* const_pointer
;
1286 typedef nsLineList_iterator iterator
;
1287 typedef nsLineList_reverse_iterator reverse_iterator
;
1288 typedef nsLineList_const_iterator const_iterator
;
1289 typedef nsLineList_const_reverse_iterator const_reverse_iterator
;
1293 MOZ_COUNT_CTOR(nsLineList
);
1299 MOZ_COUNT_DTOR(nsLineList
);
1302 const_iterator
begin() const
1305 rv
.mCurrent
= mLink
._mNext
;
1307 rv
.mListLink
= &mLink
;
1315 rv
.mCurrent
= mLink
._mNext
;
1317 rv
.mListLink
= &mLink
;
1322 iterator
begin(nsLineBox
* aLine
)
1325 rv
.mCurrent
= aLine
;
1327 rv
.mListLink
= &mLink
;
1332 const_iterator
end() const
1335 rv
.mCurrent
= &mLink
;
1337 rv
.mListLink
= &mLink
;
1345 rv
.mCurrent
= &mLink
;
1347 rv
.mListLink
= &mLink
;
1352 const_reverse_iterator
rbegin() const
1354 const_reverse_iterator rv
;
1355 rv
.mCurrent
= mLink
._mPrev
;
1357 rv
.mListLink
= &mLink
;
1362 reverse_iterator
rbegin()
1364 reverse_iterator rv
;
1365 rv
.mCurrent
= mLink
._mPrev
;
1367 rv
.mListLink
= &mLink
;
1372 reverse_iterator
rbegin(nsLineBox
* aLine
)
1374 reverse_iterator rv
;
1375 rv
.mCurrent
= aLine
;
1377 rv
.mListLink
= &mLink
;
1382 const_reverse_iterator
rend() const
1384 const_reverse_iterator rv
;
1385 rv
.mCurrent
= &mLink
;
1387 rv
.mListLink
= &mLink
;
1392 reverse_iterator
rend()
1394 reverse_iterator rv
;
1395 rv
.mCurrent
= &mLink
;
1397 rv
.mListLink
= &mLink
;
1404 return mLink
._mNext
== &mLink
;
1408 size_type
size() const
1410 size_type count
= 0;
1411 for (const link_type
*cur
= mLink
._mNext
;
1422 NS_ASSERTION(!empty(), "no element to return");
1423 return static_cast<pointer
>(mLink
._mNext
);
1426 const_pointer
front() const
1428 NS_ASSERTION(!empty(), "no element to return");
1429 return static_cast<const_pointer
>(mLink
._mNext
);
1434 NS_ASSERTION(!empty(), "no element to return");
1435 return static_cast<pointer
>(mLink
._mPrev
);
1438 const_pointer
back() const
1440 NS_ASSERTION(!empty(), "no element to return");
1441 return static_cast<const_pointer
>(mLink
._mPrev
);
1444 void push_front(pointer aNew
)
1446 aNew
->_mNext
= mLink
._mNext
;
1447 mLink
._mNext
->_mPrev
= aNew
;
1448 aNew
->_mPrev
= &mLink
;
1449 mLink
._mNext
= aNew
;
1453 // NOTE: leaves dangling next/prev pointers
1455 NS_ASSERTION(!empty(), "no element to pop");
1456 link_type
*newFirst
= mLink
._mNext
->_mNext
;
1457 newFirst
->_mPrev
= &mLink
;
1458 // mLink._mNext->_mNext = nullptr;
1459 // mLink._mNext->_mPrev = nullptr;
1460 mLink
._mNext
= newFirst
;
1463 void push_back(pointer aNew
)
1465 aNew
->_mPrev
= mLink
._mPrev
;
1466 mLink
._mPrev
->_mNext
= aNew
;
1467 aNew
->_mNext
= &mLink
;
1468 mLink
._mPrev
= aNew
;
1472 // NOTE: leaves dangling next/prev pointers
1474 NS_ASSERTION(!empty(), "no element to pop");
1475 link_type
*newLast
= mLink
._mPrev
->_mPrev
;
1476 newLast
->_mNext
= &mLink
;
1477 // mLink._mPrev->_mPrev = nullptr;
1478 // mLink._mPrev->_mNext = nullptr;
1479 mLink
._mPrev
= newLast
;
1482 // inserts x before position
1483 iterator
before_insert(iterator position
, pointer x
)
1485 // use |mCurrent| to prevent DEBUG_PASS_END assertions
1486 x
->_mPrev
= position
.mCurrent
->_mPrev
;
1487 x
->_mNext
= position
.mCurrent
;
1488 position
.mCurrent
->_mPrev
->_mNext
= x
;
1489 position
.mCurrent
->_mPrev
= x
;
1493 // inserts x after position
1494 iterator
after_insert(iterator position
, pointer x
)
1496 // use |mCurrent| to prevent DEBUG_PASS_END assertions
1497 x
->_mNext
= position
.mCurrent
->_mNext
;
1498 x
->_mPrev
= position
.mCurrent
;
1499 position
.mCurrent
->_mNext
->_mPrev
= x
;
1500 position
.mCurrent
->_mNext
= x
;
1504 // returns iterator pointing to after the element
1505 iterator
erase(iterator position
)
1506 // NOTE: leaves dangling next/prev pointers
1508 position
->_mPrev
->_mNext
= position
->_mNext
;
1509 position
->_mNext
->_mPrev
= position
->_mPrev
;
1513 void swap(self_type
& y
)
1515 link_type
tmp(y
.mLink
);
1520 mLink
._mNext
->_mPrev
= &mLink
;
1521 mLink
._mPrev
->_mNext
= &mLink
;
1525 y
.mLink
._mNext
->_mPrev
= &y
.mLink
;
1526 y
.mLink
._mPrev
->_mNext
= &y
.mLink
;
1531 // NOTE: leaves dangling next/prev pointers
1533 mLink
._mNext
= &mLink
;
1534 mLink
._mPrev
= &mLink
;
1537 // inserts the conts of x before position and makes x empty
1538 void splice(iterator position
, self_type
& x
)
1540 // use |mCurrent| to prevent DEBUG_PASS_END assertions
1541 position
.mCurrent
->_mPrev
->_mNext
= x
.mLink
._mNext
;
1542 x
.mLink
._mNext
->_mPrev
= position
.mCurrent
->_mPrev
;
1543 x
.mLink
._mPrev
->_mNext
= position
.mCurrent
;
1544 position
.mCurrent
->_mPrev
= x
.mLink
._mPrev
;
1548 // Inserts element *i from list x before position and removes
1550 void splice(iterator position
, self_type
& x
, iterator i
)
1552 NS_ASSERTION(!x
.empty(), "Can't insert from empty list.");
1553 NS_ASSERTION(position
!= i
&& position
.mCurrent
!= i
->_mNext
,
1554 "We don't check for this case.");
1557 i
->_mPrev
->_mNext
= i
->_mNext
;
1558 i
->_mNext
->_mPrev
= i
->_mPrev
;
1560 // use |mCurrent| to prevent DEBUG_PASS_END assertions
1561 // link into |this|, before-side
1562 i
->_mPrev
= position
.mCurrent
->_mPrev
;
1563 position
.mCurrent
->_mPrev
->_mNext
= i
.get();
1565 // link into |this|, after-side
1566 i
->_mNext
= position
.mCurrent
;
1567 position
.mCurrent
->_mPrev
= i
.get();
1570 // Inserts elements in [|first|, |last|), which are in |x|,
1571 // into |this| before |position| and removes them from |x|.
1572 void splice(iterator position
, self_type
& x
, iterator first
,
1575 NS_ASSERTION(!x
.empty(), "Can't insert from empty list.");
1580 --last
; // so we now want to move [first, last]
1582 first
->_mPrev
->_mNext
= last
->_mNext
;
1583 last
->_mNext
->_mPrev
= first
->_mPrev
;
1585 // use |mCurrent| to prevent DEBUG_PASS_END assertions
1586 // link into |this|, before-side
1587 first
->_mPrev
= position
.mCurrent
->_mPrev
;
1588 position
.mCurrent
->_mPrev
->_mNext
= first
.get();
1590 // link into |this|, after-side
1591 last
->_mNext
= position
.mCurrent
;
1592 position
.mCurrent
->_mPrev
= last
.get();
1598 // Many of these implementations of operator= don't work yet. I don't
1603 // NOTE: ASSIGN_FROM is meant to be used *only* as the entire body
1604 // of a function and therefore lacks PR_{BEGIN,END}_MACRO
1605 #define ASSIGN_FROM(other_) \
1606 mCurrent = other_.mCurrent; \
1607 mListLink = other_.mListLink; \
1610 #else /* !NS_LINELIST_DEBUG_PASS_END */
1612 #define ASSIGN_FROM(other_) \
1613 mCurrent = other_.mCurrent; \
1616 #endif /* !NS_LINELIST_DEBUG_PASS_END */
1619 nsLineList_iterator
&
1620 nsLineList_iterator::operator=(const nsLineList_iterator
& aOther
)
1626 nsLineList_iterator
&
1627 nsLineList_iterator::operator=(const nsLineList_reverse_iterator
& aOther
)
1633 nsLineList_reverse_iterator
&
1634 nsLineList_reverse_iterator::operator=(const nsLineList_iterator
& aOther
)
1640 nsLineList_reverse_iterator
&
1641 nsLineList_reverse_iterator::operator=(const nsLineList_reverse_iterator
& aOther
)
1647 nsLineList_const_iterator
&
1648 nsLineList_const_iterator::operator=(const nsLineList_iterator
& aOther
)
1654 nsLineList_const_iterator
&
1655 nsLineList_const_iterator::operator=(const nsLineList_reverse_iterator
& aOther
)
1661 nsLineList_const_iterator
&
1662 nsLineList_const_iterator::operator=(const nsLineList_const_iterator
& aOther
)
1668 nsLineList_const_iterator
&
1669 nsLineList_const_iterator::operator=(const nsLineList_const_reverse_iterator
& aOther
)
1675 nsLineList_const_reverse_iterator
&
1676 nsLineList_const_reverse_iterator::operator=(const nsLineList_iterator
& aOther
)
1682 nsLineList_const_reverse_iterator
&
1683 nsLineList_const_reverse_iterator::operator=(const nsLineList_reverse_iterator
& aOther
)
1689 nsLineList_const_reverse_iterator
&
1690 nsLineList_const_reverse_iterator::operator=(const nsLineList_const_iterator
& aOther
)
1696 nsLineList_const_reverse_iterator
&
1697 nsLineList_const_reverse_iterator::operator=(const nsLineList_const_reverse_iterator
& aOther
)
1703 //----------------------------------------------------------------------
1705 class nsLineIterator MOZ_FINAL
: public nsILineIterator
1711 virtual void DisposeLineIterator() MOZ_OVERRIDE
;
1713 virtual int32_t GetNumLines() MOZ_OVERRIDE
;
1714 virtual bool GetDirection() MOZ_OVERRIDE
;
1715 NS_IMETHOD
GetLine(int32_t aLineNumber
,
1716 nsIFrame
** aFirstFrameOnLine
,
1717 int32_t* aNumFramesOnLine
,
1718 nsRect
& aLineBounds
) MOZ_OVERRIDE
;
1719 virtual int32_t FindLineContaining(nsIFrame
* aFrame
, int32_t aStartLine
= 0) MOZ_OVERRIDE
;
1720 NS_IMETHOD
FindFrameAt(int32_t aLineNumber
,
1722 nsIFrame
** aFrameFound
,
1723 bool* aPosIsBeforeFirstFrame
,
1724 bool* aPosIsAfterLastFrame
) MOZ_OVERRIDE
;
1726 NS_IMETHOD
GetNextSiblingOnLine(nsIFrame
*& aFrame
, int32_t aLineNumber
) MOZ_OVERRIDE
;
1727 NS_IMETHOD
CheckLineOrder(int32_t aLine
,
1729 nsIFrame
**aFirstVisual
,
1730 nsIFrame
**aLastVisual
) MOZ_OVERRIDE
;
1731 nsresult
Init(nsLineList
& aLines
, bool aRightToLeft
);
1734 nsLineBox
* PrevLine() {
1738 return mLines
[--mIndex
];
1741 nsLineBox
* NextLine() {
1742 if (mIndex
>= mNumLines
- 1) {
1745 return mLines
[++mIndex
];
1748 nsLineBox
* LineAt(int32_t aIndex
) {
1749 if ((aIndex
< 0) || (aIndex
>= mNumLines
)) {
1752 return mLines
[aIndex
];
1761 #endif /* nsLineBox_h___ */