2007-03-22 10:30:00 -07:00
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
// vim:cindent:ts=2:et:sw=2:
/* ***** BEGIN LICENSE BLOCK *****
* Version : MPL 1.1 / GPL 2.0 / LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 ( the " License " ) ; you may not use this file except in compliance with
* the License . You may obtain a copy of the License at
* http : //www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an " AS IS " basis ,
* WITHOUT WARRANTY OF ANY KIND , either express or implied . See the License
* for the specific language governing rights and limitations under the
* License .
*
* The Original Code is Mozilla Communicator client code .
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation .
* Portions created by the Initial Developer are Copyright ( C ) 1998
* the Initial Developer . All Rights Reserved .
*
* Contributor ( s ) :
* L . David Baron < dbaron @ dbaron . org >
* Mats Palmgren < mats . palmgren @ bredband . net >
*
* Alternatively , the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later ( the " GPL " ) ,
* or the GNU Lesser General Public License Version 2.1 or later ( the " LGPL " ) ,
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above . If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL , and not to allow others to
* use your version of this file under the terms of the MPL , indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL . If you do not delete
* the provisions above , a recipient may use your version of this file under
* the terms of any one of the MPL , the GPL or the LGPL .
*
* * * * * * END LICENSE BLOCK * * * * * */
/* representation of one line within a block frame, a CSS line box */
# ifndef nsLineBox_h___
# define nsLineBox_h___
# include "nsPlaceholderFrame.h"
# include "nsILineIterator.h"
class nsSpaceManager ;
class nsLineBox ;
class nsFloatCache ;
class nsFloatCacheList ;
class nsFloatCacheFreeList ;
// State cached after reflowing a float. This state is used during
// incremental reflow when we avoid reflowing a float.
class nsFloatCache {
public :
nsFloatCache ( ) ;
# ifdef NS_BUILD_REFCNT_LOGGING
~ nsFloatCache ( ) ;
# else
~ nsFloatCache ( ) { }
# endif
nsFloatCache * Next ( ) const { return mNext ; }
nsPlaceholderFrame * mPlaceholder ; // nsPlaceholderFrame
// Region in the spacemanager impacted by this float; the
// coordinates are relative to the containing block frame. The
// region includes the margins around the float, but doesn't
// include the relative offsets.
nsRect mRegion ;
protected :
nsFloatCache * mNext ;
friend class nsFloatCacheList ;
friend class nsFloatCacheFreeList ;
} ;
//----------------------------------------
class nsFloatCacheList {
public :
# ifdef NS_BUILD_REFCNT_LOGGING
nsFloatCacheList ( ) ;
# else
nsFloatCacheList ( ) : mHead ( nsnull ) { }
# endif
~ nsFloatCacheList ( ) ;
PRBool IsEmpty ( ) const {
return nsnull = = mHead ;
}
PRBool NotEmpty ( ) const {
return nsnull ! = mHead ;
}
nsFloatCache * Head ( ) const {
return mHead ;
}
nsFloatCache * Tail ( ) const ;
void DeleteAll ( ) ;
nsFloatCache * Find ( nsIFrame * aOutOfFlowFrame ) ;
// Remove a nsFloatCache from this list. Deleting this nsFloatCache
// becomes the caller's responsibility.
void Remove ( nsFloatCache * aElement ) { RemoveAndReturnPrev ( aElement ) ; }
// Steal away aList's nsFloatCache objects and put them in this
// list. aList must not be empty.
void Append ( nsFloatCacheFreeList & aList ) ;
protected :
nsFloatCache * mHead ;
// Remove a nsFloatCache from this list. Deleting this nsFloatCache
// becomes the caller's responsibility. Returns the nsFloatCache that was
// before aElement, or nsnull if aElement was the first.
nsFloatCache * RemoveAndReturnPrev ( nsFloatCache * aElement ) ;
friend class nsFloatCacheFreeList ;
} ;
//---------------------------------------
// Like nsFloatCacheList, but with fast access to the tail
class nsFloatCacheFreeList : private nsFloatCacheList {
public :
# ifdef NS_BUILD_REFCNT_LOGGING
nsFloatCacheFreeList ( ) ;
~ nsFloatCacheFreeList ( ) ;
# else
nsFloatCacheFreeList ( ) : mTail ( nsnull ) { }
~ nsFloatCacheFreeList ( ) { }
# endif
// Reimplement trivial functions
PRBool IsEmpty ( ) const {
return nsnull = = mHead ;
}
nsFloatCache * Head ( ) const {
return mHead ;
}
nsFloatCache * Tail ( ) const {
return mTail ;
}
PRBool NotEmpty ( ) const {
return nsnull ! = mHead ;
}
void DeleteAll ( ) ;
// Steal away aList's nsFloatCache objects and put them on this
// free-list. aList must not be empty.
void Append ( nsFloatCacheList & aList ) ;
void Append ( nsFloatCache * aFloatCache ) ;
void Remove ( nsFloatCache * aElement ) ;
// Remove an nsFloatCache object from this list and return it, or create
// a new one if this one is empty;
nsFloatCache * Alloc ( ) ;
protected :
nsFloatCache * mTail ;
friend class nsFloatCacheList ;
} ;
//----------------------------------------------------------------------
# define LINE_MAX_BREAK_TYPE ((1 << 4) - 1)
# define LINE_MAX_CHILD_COUNT ((1 << 20) - 1)
# if NS_STYLE_CLEAR_LAST_VALUE > 15
need to rearrange the mBits bitfield ;
# endif
// Funtion to create a line box
nsLineBox * NS_NewLineBox ( nsIPresShell * aPresShell , nsIFrame * aFrame ,
PRInt32 aCount , PRBool aIsBlock ) ;
class nsLineList ;
// don't use the following names outside of this file. Instead, use
// nsLineList::iterator, etc. These are just here to allow them to
// be specified as parameters to methods of nsLineBox.
class nsLineList_iterator ;
class nsLineList_const_iterator ;
class nsLineList_reverse_iterator ;
class nsLineList_const_reverse_iterator ;
/**
* Users must have the class that is to be part of the list inherit
* from nsLineLink . If they want to be efficient , it should be the
* first base class . ( This was originally nsCLink in a templatized
* nsCList , but it ' s still useful separately . )
*/
class nsLineLink {
public :
friend class nsLineList ;
friend class nsLineList_iterator ;
friend class nsLineList_reverse_iterator ;
friend class nsLineList_const_iterator ;
friend class nsLineList_const_reverse_iterator ;
private :
nsLineLink * _mNext ; // or head
nsLineLink * _mPrev ; // or tail
} ;
/**
* The nsLineBox class represents a horizontal line of frames . It contains
* enough state to support incremental reflow of the frames , event handling
* for the frames , and rendering of the frames .
*/
class nsLineBox : public nsLineLink {
private :
nsLineBox ( nsIFrame * aFrame , PRInt32 aCount , PRBool aIsBlock ) ;
~ nsLineBox ( ) ;
// Overloaded new operator. Uses an arena (which comes from the presShell)
// to perform the allocation.
void * operator new ( size_t sz , nsIPresShell * aPresShell ) CPP_THROW_NEW ;
void operator delete ( void * aPtr , size_t sz ) ;
public :
// Use these two functions to allocate and destroy line boxes
friend nsLineBox * NS_NewLineBox ( nsIPresShell * aPresShell , nsIFrame * aFrame ,
PRInt32 aCount , PRBool aIsBlock ) ;
void Destroy ( nsIPresShell * aPresShell ) ;
// mBlock bit
PRBool IsBlock ( ) const {
return mFlags . mBlock ;
}
PRBool IsInline ( ) const {
return 0 = = mFlags . mBlock ;
}
// mDirty bit
void MarkDirty ( ) {
mFlags . mDirty = 1 ;
}
void ClearDirty ( ) {
mFlags . mDirty = 0 ;
}
PRBool IsDirty ( ) const {
return mFlags . mDirty ;
}
// mPreviousMarginDirty bit
void MarkPreviousMarginDirty ( ) {
mFlags . mPreviousMarginDirty = 1 ;
}
void ClearPreviousMarginDirty ( ) {
mFlags . mPreviousMarginDirty = 0 ;
}
PRBool IsPreviousMarginDirty ( ) const {
return mFlags . mPreviousMarginDirty ;
}
// mHasClearance bit
void SetHasClearance ( ) {
mFlags . mHasClearance = 1 ;
}
void ClearHasClearance ( ) {
mFlags . mHasClearance = 0 ;
}
PRBool HasClearance ( ) const {
return mFlags . mHasClearance ;
}
// mImpactedByFloat bit
void SetLineIsImpactedByFloat ( PRBool aValue ) {
NS_ASSERTION ( ( PR_FALSE = = aValue | | PR_TRUE = = aValue ) , " somebody is playing fast and loose with bools and bits! " ) ;
mFlags . mImpactedByFloat = aValue ;
}
PRBool IsImpactedByFloat ( ) const {
return mFlags . mImpactedByFloat ;
}
// mLineWrapped bit
void SetLineWrapped ( PRBool aOn ) {
NS_ASSERTION ( ( PR_FALSE = = aOn | | PR_TRUE = = aOn ) , " somebody is playing fast and loose with bools and bits! " ) ;
mFlags . mLineWrapped = aOn ;
}
PRBool IsLineWrapped ( ) const {
return mFlags . mLineWrapped ;
}
2007-09-17 20:00:16 -07:00
// mInvalidateTextRuns bit
void SetInvalidateTextRuns ( PRBool aOn ) {
NS_ASSERTION ( ( PR_FALSE = = aOn | | PR_TRUE = = aOn ) , " somebody is playing fast and loose with bools and bits! " ) ;
mFlags . mInvalidateTextRuns = aOn ;
}
PRBool GetInvalidateTextRuns ( ) const {
return mFlags . mInvalidateTextRuns ;
}
2007-03-22 10:30:00 -07:00
// mResizeReflowOptimizationDisabled bit
void DisableResizeReflowOptimization ( ) {
mFlags . mResizeReflowOptimizationDisabled = PR_TRUE ;
}
void EnableResizeReflowOptimization ( ) {
mFlags . mResizeReflowOptimizationDisabled = PR_FALSE ;
}
PRBool ResizeReflowOptimizationDisabled ( ) const {
return mFlags . mResizeReflowOptimizationDisabled ;
}
// mChildCount value
PRInt32 GetChildCount ( ) const {
return ( PRInt32 ) mFlags . mChildCount ;
}
void SetChildCount ( PRInt32 aNewCount ) {
if ( aNewCount < 0 ) {
NS_WARNING ( " negative child count " ) ;
aNewCount = 0 ;
}
if ( aNewCount > LINE_MAX_CHILD_COUNT ) {
aNewCount = LINE_MAX_CHILD_COUNT ;
}
mFlags . mChildCount = aNewCount ;
}
// mBreakType value
// Break information is applied *before* the line if the line is a block,
// or *after* the line if the line is an inline. Confusing, I know, but
// using different names should help.
PRBool HasBreakBefore ( ) const {
return IsBlock ( ) & & NS_STYLE_CLEAR_NONE ! = mFlags . mBreakType ;
}
void SetBreakTypeBefore ( PRUint8 aBreakType ) {
NS_ASSERTION ( IsBlock ( ) , " Only blocks have break-before " ) ;
NS_ASSERTION ( aBreakType < = NS_STYLE_CLEAR_LEFT_AND_RIGHT ,
" Only float break types are allowed before a line " ) ;
mFlags . mBreakType = aBreakType ;
}
PRUint8 GetBreakTypeBefore ( ) const {
return IsBlock ( ) ? mFlags . mBreakType : NS_STYLE_CLEAR_NONE ;
}
PRBool HasBreakAfter ( ) const {
return ! IsBlock ( ) & & NS_STYLE_CLEAR_NONE ! = mFlags . mBreakType ;
}
void SetBreakTypeAfter ( PRUint8 aBreakType ) {
NS_ASSERTION ( ! IsBlock ( ) , " Only inlines have break-after " ) ;
NS_ASSERTION ( aBreakType < = LINE_MAX_BREAK_TYPE , " bad break type " ) ;
mFlags . mBreakType = aBreakType ;
}
PRBool HasFloatBreakAfter ( ) const {
return ! IsBlock ( ) & & ( NS_STYLE_CLEAR_LEFT = = mFlags . mBreakType | |
NS_STYLE_CLEAR_RIGHT = = mFlags . mBreakType | |
NS_STYLE_CLEAR_LEFT_AND_RIGHT = = mFlags . mBreakType ) ;
}
PRUint8 GetBreakTypeAfter ( ) const {
return ! IsBlock ( ) ? mFlags . mBreakType : NS_STYLE_CLEAR_NONE ;
}
// mCarriedOutBottomMargin value
nsCollapsingMargin GetCarriedOutBottomMargin ( ) const ;
// Returns PR_TRUE if the margin changed
PRBool SetCarriedOutBottomMargin ( nsCollapsingMargin aValue ) ;
// mFloats
PRBool HasFloats ( ) const {
return ( IsInline ( ) & & mInlineData ) & & mInlineData - > mFloats . NotEmpty ( ) ;
}
nsFloatCache * GetFirstFloat ( ) ;
void FreeFloats ( nsFloatCacheFreeList & aFreeList ) ;
void AppendFloats ( nsFloatCacheFreeList & aFreeList ) ;
PRBool RemoveFloat ( nsIFrame * aFrame ) ;
// Combined area is the area of the line that should influence the
// overflow area of its parent block. The combined area should be
// used for painting-related things, but should never be used for
// layout (except for handling of 'overflow').
void SetCombinedArea ( const nsRect & aCombinedArea ) ;
nsRect GetCombinedArea ( ) {
return mData ? mData - > mCombinedArea : mBounds ;
}
PRBool CombinedAreaIntersects ( const nsRect & aDamageRect ) {
nsRect * ca = ( mData ? & mData - > mCombinedArea : & mBounds ) ;
return ! ( ( ca - > YMost ( ) < = aDamageRect . y ) | |
( ca - > y > = aDamageRect . YMost ( ) ) ) ;
}
void SlideBy ( nscoord aDY ) {
mBounds . y + = aDY ;
if ( mData ) {
mData - > mCombinedArea . y + = aDY ;
}
}
/**
* The ascent ( distance from top to baseline ) of the linebox is the
* ascent of the anonymous inline box ( for which we don ' t actually
* create a frame ) that wraps all the consecutive inline children of a
* block .
*
* This is currently unused for block lines .
*/
nscoord GetAscent ( ) const { return mAscent ; }
void SetAscent ( nscoord aAscent ) { mAscent = aAscent ; }
nscoord GetHeight ( ) const {
return mBounds . height ;
}
static void DeleteLineList ( nsPresContext * aPresContext , nsLineList & aLines ) ;
// search from beginning to end
// XXX Should switch to API below
static nsLineBox * FindLineContaining ( nsLineList & aLines , nsIFrame * aFrame ,
PRInt32 * aFrameIndexInLine ) ;
// search from end to beginning of [aBegin, aEnd)
// Returns PR_TRUE if it found the line and PR_FALSE if not.
// Moves aEnd as it searches so that aEnd points to the resulting line.
static PRBool RFindLineContaining ( nsIFrame * aFrame ,
const nsLineList_iterator & aBegin ,
nsLineList_iterator & aEnd ,
PRInt32 * aFrameIndexInLine ) ;
# ifdef DEBUG
char * StateToString ( char * aBuf , PRInt32 aBufSize ) const ;
void List ( FILE * out , PRInt32 aIndent ) const ;
# endif
nsIFrame * LastChild ( ) const ;
PRBool IsLastChild ( nsIFrame * aFrame ) const ;
PRInt32 IndexOf ( nsIFrame * aFrame ) const ;
PRBool Contains ( nsIFrame * aFrame ) const {
return IndexOf ( aFrame ) > = 0 ;
}
// whether the line box is "logically" empty (just like nsIFrame::IsEmpty)
PRBool IsEmpty ( ) const ;
// Call this only while in Reflow() for the block the line belongs
// to, only between reflowing the line (or sliding it, if we skip
// reflowing it) and the end of reflowing the block.
PRBool CachedIsEmpty ( ) ;
void InvalidateCachedIsEmpty ( ) {
mFlags . mEmptyCacheValid = PR_FALSE ;
}
// For debugging purposes
PRBool IsValidCachedIsEmpty ( ) {
return mFlags . mEmptyCacheValid ;
}
# ifdef DEBUG
static PRInt32 GetCtorCount ( ) ;
# endif
nsIFrame * mFirstChild ;
nsRect mBounds ;
struct FlagBits {
PRUint32 mDirty : 1 ;
PRUint32 mPreviousMarginDirty : 1 ;
PRUint32 mHasClearance : 1 ;
PRUint32 mBlock : 1 ;
PRUint32 mImpactedByFloat : 1 ;
PRUint32 mLineWrapped : 1 ;
2007-09-17 20:00:16 -07:00
PRUint32 mInvalidateTextRuns : 1 ;
2007-03-22 10:30:00 -07:00
PRUint32 mResizeReflowOptimizationDisabled : 1 ; // default 0 = means that the opt potentially applies to this line. 1 = never skip reflowing this line for a resize reflow
PRUint32 mEmptyCacheValid : 1 ;
PRUint32 mEmptyCacheState : 1 ;
PRUint32 mBreakType : 4 ;
PRUint32 mChildCount : 18 ;
} ;
struct ExtraData {
ExtraData ( const nsRect & aBounds ) : mCombinedArea ( aBounds ) {
}
nsRect mCombinedArea ;
} ;
struct ExtraBlockData : public ExtraData {
ExtraBlockData ( const nsRect & aBounds )
: ExtraData ( aBounds ) ,
mCarriedOutBottomMargin ( )
{
}
nsCollapsingMargin mCarriedOutBottomMargin ;
} ;
struct ExtraInlineData : public ExtraData {
ExtraInlineData ( const nsRect & aBounds ) : ExtraData ( aBounds ) {
}
nsFloatCacheList mFloats ;
} ;
protected :
nscoord mAscent ; // see |SetAscent| / |GetAscent|
union {
PRUint32 mAllFlags ;
FlagBits mFlags ;
} ;
union {
ExtraData * mData ;
ExtraBlockData * mBlockData ;
ExtraInlineData * mInlineData ;
} ;
void Cleanup ( ) ;
void MaybeFreeData ( ) ;
} ;
/**
* A linked list type where the items in the list must inherit from
* a link type to fuse allocations .
*
* API heavily based on the | list | class in the C + + standard .
*/
class nsLineList_iterator {
public :
friend class nsLineList ;
friend class nsLineList_reverse_iterator ;
friend class nsLineList_const_iterator ;
friend class nsLineList_const_reverse_iterator ;
typedef nsLineList_iterator iterator_self_type ;
typedef nsLineList_reverse_iterator iterator_reverse_type ;
typedef nsLineBox & reference ;
typedef const nsLineBox & const_reference ;
typedef nsLineBox * pointer ;
typedef const nsLineBox * const_pointer ;
typedef PRUint32 size_type ;
typedef PRInt32 difference_type ;
typedef nsLineLink link_type ;
# ifdef NS_DEBUG
nsLineList_iterator ( ) { memset ( & mCurrent , 0xcd , sizeof ( mCurrent ) ) ; }
# else
// Auto generated default constructor OK.
# endif
// Auto generated copy-constructor OK.
inline iterator_self_type &
operator = ( const iterator_self_type & aOther ) ;
inline iterator_self_type &
operator = ( const iterator_reverse_type & aOther ) ;
iterator_self_type & operator + + ( )
{
mCurrent = mCurrent - > _mNext ;
return * this ;
}
iterator_self_type operator + + ( int )
{
iterator_self_type rv ( * this ) ;
mCurrent = mCurrent - > _mNext ;
return rv ;
}
iterator_self_type & operator - - ( )
{
mCurrent = mCurrent - > _mPrev ;
return * this ;
}
iterator_self_type operator - - ( int )
{
iterator_self_type rv ( * this ) ;
mCurrent = mCurrent - > _mPrev ;
return rv ;
}
reference operator * ( )
{
2008-07-05 18:11:12 -07:00
NS_ABORT_IF_FALSE ( mCurrent ! = mListLink , " running past end " ) ;
2007-07-08 00:08:04 -07:00
return * static_cast < pointer > ( mCurrent ) ;
2007-03-22 10:30:00 -07:00
}
pointer operator - > ( )
{
2008-07-05 18:11:12 -07:00
NS_ABORT_IF_FALSE ( mCurrent ! = mListLink , " running past end " ) ;
2007-07-08 00:08:04 -07:00
return static_cast < pointer > ( mCurrent ) ;
2007-03-22 10:30:00 -07:00
}
pointer get ( )
{
2008-07-05 18:11:12 -07:00
NS_ABORT_IF_FALSE ( mCurrent ! = mListLink , " running past end " ) ;
2007-07-08 00:08:04 -07:00
return static_cast < pointer > ( mCurrent ) ;
2007-03-22 10:30:00 -07:00
}
operator pointer ( )
{
2008-07-05 18:11:12 -07:00
NS_ABORT_IF_FALSE ( mCurrent ! = mListLink , " running past end " ) ;
2007-07-08 00:08:04 -07:00
return static_cast < pointer > ( mCurrent ) ;
2007-03-22 10:30:00 -07:00
}
const_reference operator * ( ) const
{
2008-07-05 18:11:12 -07:00
NS_ABORT_IF_FALSE ( mCurrent ! = mListLink , " running past end " ) ;
2007-07-08 00:08:04 -07:00
return * static_cast < const_pointer > ( mCurrent ) ;
2007-03-22 10:30:00 -07:00
}
const_pointer operator - > ( ) const
{
2008-07-05 18:11:12 -07:00
NS_ABORT_IF_FALSE ( mCurrent ! = mListLink , " running past end " ) ;
2007-07-08 00:08:04 -07:00
return static_cast < const_pointer > ( mCurrent ) ;
2007-03-22 10:30:00 -07:00
}
# ifndef __MWERKS__
operator const_pointer ( ) const
{
2008-07-05 18:11:12 -07:00
NS_ABORT_IF_FALSE ( mCurrent ! = mListLink , " running past end " ) ;
2007-07-08 00:08:04 -07:00
return static_cast < const_pointer > ( mCurrent ) ;
2007-03-22 10:30:00 -07:00
}
# endif /* !__MWERKS__ */
iterator_self_type next ( )
{
iterator_self_type copy ( * this ) ;
return + + copy ;
}
const iterator_self_type next ( ) const
{
iterator_self_type copy ( * this ) ;
return + + copy ;
}
iterator_self_type prev ( )
{
iterator_self_type copy ( * this ) ;
return - - copy ;
}
const iterator_self_type prev ( ) const
{
iterator_self_type copy ( * this ) ;
return - - copy ;
}
// Passing by value rather than by reference and reference to const
// to keep AIX happy.
PRBool operator = = ( const iterator_self_type aOther ) const
2007-07-10 17:55:15 -07:00
{
NS_ASSERTION ( mListLink = = aOther . mListLink , " comparing iterators over different lists " ) ;
return mCurrent = = aOther . mCurrent ;
}
2007-03-22 10:30:00 -07:00
PRBool operator ! = ( const iterator_self_type aOther ) const
2007-07-10 17:55:15 -07:00
{
NS_ASSERTION ( mListLink = = aOther . mListLink , " comparing iterators over different lists " ) ;
return mCurrent ! = aOther . mCurrent ;
}
2007-03-22 10:30:00 -07:00
PRBool operator = = ( const iterator_self_type aOther )
2007-07-10 17:55:15 -07:00
{
NS_ASSERTION ( mListLink = = aOther . mListLink , " comparing iterators over different lists " ) ;
return mCurrent = = aOther . mCurrent ;
}
2007-03-22 10:30:00 -07:00
PRBool operator ! = ( const iterator_self_type aOther )
2007-07-10 17:55:15 -07:00
{
NS_ASSERTION ( mListLink = = aOther . mListLink , " comparing iterators over different lists " ) ;
return mCurrent ! = aOther . mCurrent ;
}
2007-03-22 10:30:00 -07:00
private :
link_type * mCurrent ;
2007-08-02 15:43:14 -07:00
# ifdef DEBUG
2007-03-22 10:30:00 -07:00
link_type * mListLink ; // the list's link, i.e., the end
# endif
} ;
class nsLineList_reverse_iterator {
public :
friend class nsLineList ;
friend class nsLineList_iterator ;
friend class nsLineList_const_iterator ;
friend class nsLineList_const_reverse_iterator ;
typedef nsLineList_reverse_iterator iterator_self_type ;
typedef nsLineList_iterator iterator_reverse_type ;
typedef nsLineBox & reference ;
typedef const nsLineBox & const_reference ;
typedef nsLineBox * pointer ;
typedef const nsLineBox * const_pointer ;
typedef PRUint32 size_type ;
typedef PRInt32 difference_type ;
typedef nsLineLink link_type ;
# ifdef NS_DEBUG
nsLineList_reverse_iterator ( ) { memset ( & mCurrent , 0xcd , sizeof ( mCurrent ) ) ; }
# else
// Auto generated default constructor OK.
# endif
// Auto generated copy-constructor OK.
inline iterator_self_type &
operator = ( const iterator_reverse_type & aOther ) ;
inline iterator_self_type &
operator = ( const iterator_self_type & aOther ) ;
iterator_self_type & operator + + ( )
{
mCurrent = mCurrent - > _mPrev ;
return * this ;
}
iterator_self_type operator + + ( int )
{
iterator_self_type rv ( * this ) ;
mCurrent = mCurrent - > _mPrev ;
return rv ;
}
iterator_self_type & operator - - ( )
{
mCurrent = mCurrent - > _mNext ;
return * this ;
}
iterator_self_type operator - - ( int )
{
iterator_self_type rv ( * this ) ;
mCurrent = mCurrent - > _mNext ;
return rv ;
}
reference operator * ( )
{
2008-07-05 18:11:12 -07:00
NS_ABORT_IF_FALSE ( mCurrent ! = mListLink , " running past end " ) ;
2007-07-08 00:08:04 -07:00
return * static_cast < pointer > ( mCurrent ) ;
2007-03-22 10:30:00 -07:00
}
pointer operator - > ( )
{
2008-07-05 18:11:12 -07:00
NS_ABORT_IF_FALSE ( mCurrent ! = mListLink , " running past end " ) ;
2007-07-08 00:08:04 -07:00
return static_cast < pointer > ( mCurrent ) ;
2007-03-22 10:30:00 -07:00
}
pointer get ( )
{
2008-07-05 18:11:12 -07:00
NS_ABORT_IF_FALSE ( mCurrent ! = mListLink , " running past end " ) ;
2007-07-08 00:08:04 -07:00
return static_cast < pointer > ( mCurrent ) ;
2007-03-22 10:30:00 -07:00
}
operator pointer ( )
{
2008-07-05 18:11:12 -07:00
NS_ABORT_IF_FALSE ( mCurrent ! = mListLink , " running past end " ) ;
2007-07-08 00:08:04 -07:00
return static_cast < pointer > ( mCurrent ) ;
2007-03-22 10:30:00 -07:00
}
const_reference operator * ( ) const
{
2008-07-05 18:11:12 -07:00
NS_ABORT_IF_FALSE ( mCurrent ! = mListLink , " running past end " ) ;
2007-07-08 00:08:04 -07:00
return * static_cast < const_pointer > ( mCurrent ) ;
2007-03-22 10:30:00 -07:00
}
const_pointer operator - > ( ) const
{
2008-07-05 18:11:12 -07:00
NS_ABORT_IF_FALSE ( mCurrent ! = mListLink , " running past end " ) ;
2007-07-08 00:08:04 -07:00
return static_cast < const_pointer > ( mCurrent ) ;
2007-03-22 10:30:00 -07:00
}
# ifndef __MWERKS__
operator const_pointer ( ) const
{
2008-07-05 18:11:12 -07:00
NS_ABORT_IF_FALSE ( mCurrent ! = mListLink , " running past end " ) ;
2007-07-08 00:08:04 -07:00
return static_cast < const_pointer > ( mCurrent ) ;
2007-03-22 10:30:00 -07:00
}
# endif /* !__MWERKS__ */
// Passing by value rather than by reference and reference to const
// to keep AIX happy.
PRBool operator = = ( const iterator_self_type aOther ) const
2007-08-02 15:43:14 -07:00
{
NS_ASSERTION ( mListLink = = aOther . mListLink , " comparing iterators over different lists " ) ;
return mCurrent = = aOther . mCurrent ;
}
2007-03-22 10:30:00 -07:00
PRBool operator ! = ( const iterator_self_type aOther ) const
2007-08-02 15:43:14 -07:00
{
NS_ASSERTION ( mListLink = = aOther . mListLink , " comparing iterators over different lists " ) ;
return mCurrent ! = aOther . mCurrent ;
}
2007-03-22 10:30:00 -07:00
PRBool operator = = ( const iterator_self_type aOther )
2007-08-02 15:43:14 -07:00
{
NS_ASSERTION ( mListLink = = aOther . mListLink , " comparing iterators over different lists " ) ;
return mCurrent = = aOther . mCurrent ;
}
2007-03-22 10:30:00 -07:00
PRBool operator ! = ( const iterator_self_type aOther )
2007-08-02 15:43:14 -07:00
{
NS_ASSERTION ( mListLink = = aOther . mListLink , " comparing iterators over different lists " ) ;
return mCurrent ! = aOther . mCurrent ;
}
2007-03-22 10:30:00 -07:00
private :
link_type * mCurrent ;
2007-08-02 15:43:14 -07:00
# ifdef DEBUG
2007-03-22 10:30:00 -07:00
link_type * mListLink ; // the list's link, i.e., the end
# endif
} ;
class nsLineList_const_iterator {
public :
friend class nsLineList ;
friend class nsLineList_iterator ;
friend class nsLineList_reverse_iterator ;
friend class nsLineList_const_reverse_iterator ;
typedef nsLineList_const_iterator iterator_self_type ;
typedef nsLineList_const_reverse_iterator iterator_reverse_type ;
typedef nsLineList_iterator iterator_nonconst_type ;
typedef nsLineList_reverse_iterator iterator_nonconst_reverse_type ;
typedef nsLineBox & reference ;
typedef const nsLineBox & const_reference ;
typedef nsLineBox * pointer ;
typedef const nsLineBox * const_pointer ;
typedef PRUint32 size_type ;
typedef PRInt32 difference_type ;
typedef nsLineLink link_type ;
2007-08-02 15:43:14 -07:00
# ifdef DEBUG
2007-03-22 10:30:00 -07:00
nsLineList_const_iterator ( ) { memset ( & mCurrent , 0xcd , sizeof ( mCurrent ) ) ; }
# else
// Auto generated default constructor OK.
# endif
// Auto generated copy-constructor OK.
inline iterator_self_type &
operator = ( const iterator_nonconst_type & aOther ) ;
inline iterator_self_type &
operator = ( const iterator_nonconst_reverse_type & aOther ) ;
inline iterator_self_type &
operator = ( const iterator_self_type & aOther ) ;
inline iterator_self_type &
operator = ( const iterator_reverse_type & aOther ) ;
iterator_self_type & operator + + ( )
{
mCurrent = mCurrent - > _mNext ;
return * this ;
}
iterator_self_type operator + + ( int )
{
iterator_self_type rv ( * this ) ;
mCurrent = mCurrent - > _mNext ;
return rv ;
}
iterator_self_type & operator - - ( )
{
mCurrent = mCurrent - > _mPrev ;
return * this ;
}
iterator_self_type operator - - ( int )
{
iterator_self_type rv ( * this ) ;
mCurrent = mCurrent - > _mPrev ;
return rv ;
}
const_reference operator * ( ) const
{
2008-07-05 18:11:12 -07:00
NS_ABORT_IF_FALSE ( mCurrent ! = mListLink , " running past end " ) ;
2007-07-08 00:08:04 -07:00
return * static_cast < const_pointer > ( mCurrent ) ;
2007-03-22 10:30:00 -07:00
}
const_pointer operator - > ( ) const
{
2008-07-05 18:11:12 -07:00
NS_ABORT_IF_FALSE ( mCurrent ! = mListLink , " running past end " ) ;
2007-07-08 00:08:04 -07:00
return static_cast < const_pointer > ( mCurrent ) ;
2007-03-22 10:30:00 -07:00
}
const_pointer get ( ) const
{
2008-07-05 18:11:12 -07:00
NS_ABORT_IF_FALSE ( mCurrent ! = mListLink , " running past end " ) ;
2007-07-08 00:08:04 -07:00
return static_cast < const_pointer > ( mCurrent ) ;
2007-03-22 10:30:00 -07:00
}
# ifndef __MWERKS__
operator const_pointer ( ) const
{
2008-07-05 18:11:12 -07:00
NS_ABORT_IF_FALSE ( mCurrent ! = mListLink , " running past end " ) ;
2007-07-08 00:08:04 -07:00
return static_cast < const_pointer > ( mCurrent ) ;
2007-03-22 10:30:00 -07:00
}
# endif /* !__MWERKS__ */
const iterator_self_type next ( ) const
{
iterator_self_type copy ( * this ) ;
return + + copy ;
}
const iterator_self_type prev ( ) const
{
iterator_self_type copy ( * this ) ;
return - - copy ;
}
// Passing by value rather than by reference and reference to const
// to keep AIX happy.
PRBool operator = = ( const iterator_self_type aOther ) const
2007-08-02 15:43:14 -07:00
{
NS_ASSERTION ( mListLink = = aOther . mListLink , " comparing iterators over different lists " ) ;
return mCurrent = = aOther . mCurrent ;
}
2007-03-22 10:30:00 -07:00
PRBool operator ! = ( const iterator_self_type aOther ) const
2007-08-02 15:43:14 -07:00
{
NS_ASSERTION ( mListLink = = aOther . mListLink , " comparing iterators over different lists " ) ;
return mCurrent ! = aOther . mCurrent ;
}
2007-03-22 10:30:00 -07:00
PRBool operator = = ( const iterator_self_type aOther )
2007-08-02 15:43:14 -07:00
{
NS_ASSERTION ( mListLink = = aOther . mListLink , " comparing iterators over different lists " ) ;
return mCurrent = = aOther . mCurrent ;
}
2007-03-22 10:30:00 -07:00
PRBool operator ! = ( const iterator_self_type aOther )
2007-08-02 15:43:14 -07:00
{
NS_ASSERTION ( mListLink = = aOther . mListLink , " comparing iterators over different lists " ) ;
return mCurrent ! = aOther . mCurrent ;
}
2007-03-22 10:30:00 -07:00
private :
const link_type * mCurrent ;
2007-08-02 15:43:14 -07:00
# ifdef DEBUG
2007-03-22 10:30:00 -07:00
const link_type * mListLink ; // the list's link, i.e., the end
# endif
} ;
class nsLineList_const_reverse_iterator {
public :
friend class nsLineList ;
friend class nsLineList_iterator ;
friend class nsLineList_reverse_iterator ;
friend class nsLineList_const_iterator ;
typedef nsLineList_const_reverse_iterator iterator_self_type ;
typedef nsLineList_const_iterator iterator_reverse_type ;
typedef nsLineList_iterator iterator_nonconst_reverse_type ;
typedef nsLineList_reverse_iterator iterator_nonconst_type ;
typedef nsLineBox & reference ;
typedef const nsLineBox & const_reference ;
typedef nsLineBox * pointer ;
typedef const nsLineBox * const_pointer ;
typedef PRUint32 size_type ;
typedef PRInt32 difference_type ;
typedef nsLineLink link_type ;
2007-08-02 15:43:14 -07:00
# ifdef DEBUG
2007-03-22 10:30:00 -07:00
nsLineList_const_reverse_iterator ( ) { memset ( & mCurrent , 0xcd , sizeof ( mCurrent ) ) ; }
# else
// Auto generated default constructor OK.
# endif
// Auto generated copy-constructor OK.
inline iterator_self_type &
operator = ( const iterator_nonconst_type & aOther ) ;
inline iterator_self_type &
operator = ( const iterator_nonconst_reverse_type & aOther ) ;
inline iterator_self_type &
operator = ( const iterator_self_type & aOther ) ;
inline iterator_self_type &
operator = ( const iterator_reverse_type & aOther ) ;
iterator_self_type & operator + + ( )
{
mCurrent = mCurrent - > _mPrev ;
return * this ;
}
iterator_self_type operator + + ( int )
{
iterator_self_type rv ( * this ) ;
mCurrent = mCurrent - > _mPrev ;
return rv ;
}
iterator_self_type & operator - - ( )
{
mCurrent = mCurrent - > _mNext ;
return * this ;
}
iterator_self_type operator - - ( int )
{
iterator_self_type rv ( * this ) ;
mCurrent = mCurrent - > _mNext ;
return rv ;
}
const_reference operator * ( ) const
{
2008-07-05 18:11:12 -07:00
NS_ABORT_IF_FALSE ( mCurrent ! = mListLink , " running past end " ) ;
2007-07-08 00:08:04 -07:00
return * static_cast < const_pointer > ( mCurrent ) ;
2007-03-22 10:30:00 -07:00
}
const_pointer operator - > ( ) const
{
2008-07-05 18:11:12 -07:00
NS_ABORT_IF_FALSE ( mCurrent ! = mListLink , " running past end " ) ;
2007-07-08 00:08:04 -07:00
return static_cast < const_pointer > ( mCurrent ) ;
2007-03-22 10:30:00 -07:00
}
const_pointer get ( ) const
{
2008-07-05 18:11:12 -07:00
NS_ABORT_IF_FALSE ( mCurrent ! = mListLink , " running past end " ) ;
2007-07-08 00:08:04 -07:00
return static_cast < const_pointer > ( mCurrent ) ;
2007-03-22 10:30:00 -07:00
}
# ifndef __MWERKS__
operator const_pointer ( ) const
{
2008-07-05 18:11:12 -07:00
NS_ABORT_IF_FALSE ( mCurrent ! = mListLink , " running past end " ) ;
2007-07-08 00:08:04 -07:00
return static_cast < const_pointer > ( mCurrent ) ;
2007-03-22 10:30:00 -07:00
}
# endif /* !__MWERKS__ */
// Passing by value rather than by reference and reference to const
// to keep AIX happy.
PRBool operator = = ( const iterator_self_type aOther ) const
2007-08-02 15:43:14 -07:00
{
NS_ASSERTION ( mListLink = = aOther . mListLink , " comparing iterators over different lists " ) ;
return mCurrent = = aOther . mCurrent ;
}
2007-03-22 10:30:00 -07:00
PRBool operator ! = ( const iterator_self_type aOther ) const
2007-08-02 15:43:14 -07:00
{
NS_ASSERTION ( mListLink = = aOther . mListLink , " comparing iterators over different lists " ) ;
return mCurrent ! = aOther . mCurrent ;
}
2007-03-22 10:30:00 -07:00
PRBool operator = = ( const iterator_self_type aOther )
2007-08-02 15:43:14 -07:00
{
NS_ASSERTION ( mListLink = = aOther . mListLink , " comparing iterators over different lists " ) ;
return mCurrent = = aOther . mCurrent ;
}
2007-03-22 10:30:00 -07:00
PRBool operator ! = ( const iterator_self_type aOther )
2007-08-02 15:43:14 -07:00
{
NS_ASSERTION ( mListLink = = aOther . mListLink , " comparing iterators over different lists " ) ;
return mCurrent ! = aOther . mCurrent ;
}
2007-03-22 10:30:00 -07:00
//private:
const link_type * mCurrent ;
2007-08-02 15:43:14 -07:00
# ifdef DEBUG
2007-03-22 10:30:00 -07:00
const link_type * mListLink ; // the list's link, i.e., the end
# endif
} ;
class nsLineList {
public :
friend class nsLineList_iterator ;
friend class nsLineList_reverse_iterator ;
friend class nsLineList_const_iterator ;
friend class nsLineList_const_reverse_iterator ;
typedef PRUint32 size_type ;
typedef PRInt32 difference_type ;
typedef nsLineLink link_type ;
private :
link_type mLink ;
public :
typedef nsLineList self_type ;
typedef nsLineBox & reference ;
typedef const nsLineBox & const_reference ;
typedef nsLineBox * pointer ;
typedef const nsLineBox * const_pointer ;
typedef nsLineList_iterator iterator ;
typedef nsLineList_reverse_iterator reverse_iterator ;
typedef nsLineList_const_iterator const_iterator ;
typedef nsLineList_const_reverse_iterator const_reverse_iterator ;
nsLineList ( )
{
clear ( ) ;
}
const_iterator begin ( ) const
{
const_iterator rv ;
rv . mCurrent = mLink . _mNext ;
2007-08-02 15:43:14 -07:00
# ifdef DEBUG
2007-03-22 10:30:00 -07:00
rv . mListLink = & mLink ;
# endif
return rv ;
}
iterator begin ( )
{
iterator rv ;
rv . mCurrent = mLink . _mNext ;
2007-08-02 15:43:14 -07:00
# ifdef DEBUG
2007-03-22 10:30:00 -07:00
rv . mListLink = & mLink ;
# endif
return rv ;
}
iterator begin ( nsLineBox * aLine )
{
iterator rv ;
rv . mCurrent = aLine ;
2007-08-02 15:43:14 -07:00
# ifdef DEBUG
2007-03-22 10:30:00 -07:00
rv . mListLink = & mLink ;
# endif
return rv ;
}
const_iterator end ( ) const
{
const_iterator rv ;
rv . mCurrent = & mLink ;
2007-08-02 15:43:14 -07:00
# ifdef DEBUG
2007-03-22 10:30:00 -07:00
rv . mListLink = & mLink ;
# endif
return rv ;
}
iterator end ( )
{
iterator rv ;
rv . mCurrent = & mLink ;
2007-08-02 15:43:14 -07:00
# ifdef DEBUG
2007-03-22 10:30:00 -07:00
rv . mListLink = & mLink ;
# endif
return rv ;
}
const_reverse_iterator rbegin ( ) const
{
const_reverse_iterator rv ;
rv . mCurrent = mLink . _mPrev ;
2007-08-02 15:43:14 -07:00
# ifdef DEBUG
2007-03-22 10:30:00 -07:00
rv . mListLink = & mLink ;
# endif
return rv ;
}
reverse_iterator rbegin ( )
{
reverse_iterator rv ;
rv . mCurrent = mLink . _mPrev ;
2007-08-02 15:43:14 -07:00
# ifdef DEBUG
2007-03-22 10:30:00 -07:00
rv . mListLink = & mLink ;
# endif
return rv ;
}
const_reverse_iterator rend ( ) const
{
const_reverse_iterator rv ;
rv . mCurrent = & mLink ;
2007-08-02 15:43:14 -07:00
# ifdef DEBUG
2007-03-22 10:30:00 -07:00
rv . mListLink = & mLink ;
# endif
return rv ;
}
reverse_iterator rend ( )
{
reverse_iterator rv ;
rv . mCurrent = & mLink ;
2007-08-02 15:43:14 -07:00
# ifdef DEBUG
2007-03-22 10:30:00 -07:00
rv . mListLink = & mLink ;
# endif
return rv ;
}
PRBool empty ( ) const
{
return mLink . _mNext = = & mLink ;
}
// NOTE: O(N).
size_type size ( ) const
{
size_type count = 0 ;
for ( const link_type * cur = mLink . _mNext ;
cur ! = & mLink ;
cur = cur - > _mNext )
{
+ + count ;
}
return count ;
}
pointer front ( )
{
NS_ASSERTION ( ! empty ( ) , " no element to return " ) ;
2007-07-08 00:08:04 -07:00
return static_cast < pointer > ( mLink . _mNext ) ;
2007-03-22 10:30:00 -07:00
}
const_pointer front ( ) const
{
NS_ASSERTION ( ! empty ( ) , " no element to return " ) ;
2007-07-08 00:08:04 -07:00
return static_cast < const_pointer > ( mLink . _mNext ) ;
2007-03-22 10:30:00 -07:00
}
pointer back ( )
{
NS_ASSERTION ( ! empty ( ) , " no element to return " ) ;
2007-07-08 00:08:04 -07:00
return static_cast < pointer > ( mLink . _mPrev ) ;
2007-03-22 10:30:00 -07:00
}
const_pointer back ( ) const
{
NS_ASSERTION ( ! empty ( ) , " no element to return " ) ;
2007-07-08 00:08:04 -07:00
return static_cast < const_pointer > ( mLink . _mPrev ) ;
2007-03-22 10:30:00 -07:00
}
void push_front ( pointer aNew )
{
aNew - > _mNext = mLink . _mNext ;
mLink . _mNext - > _mPrev = aNew ;
aNew - > _mPrev = & mLink ;
mLink . _mNext = aNew ;
}
void pop_front ( )
// NOTE: leaves dangling next/prev pointers
{
NS_ASSERTION ( ! empty ( ) , " no element to pop " ) ;
link_type * newFirst = mLink . _mNext - > _mNext ;
newFirst - > _mPrev = & mLink ;
// mLink._mNext->_mNext = nsnull;
// mLink._mNext->_mPrev = nsnull;
mLink . _mNext = newFirst ;
}
void push_back ( pointer aNew )
{
aNew - > _mPrev = mLink . _mPrev ;
mLink . _mPrev - > _mNext = aNew ;
aNew - > _mNext = & mLink ;
mLink . _mPrev = aNew ;
}
void pop_back ( )
// NOTE: leaves dangling next/prev pointers
{
NS_ASSERTION ( ! empty ( ) , " no element to pop " ) ;
link_type * newLast = mLink . _mPrev - > _mPrev ;
newLast - > _mNext = & mLink ;
// mLink._mPrev->_mPrev = nsnull;
// mLink._mPrev->_mNext = nsnull;
mLink . _mPrev = newLast ;
}
// inserts x before position
iterator before_insert ( iterator position , pointer x )
{
// use |mCurrent| to prevent DEBUG_PASS_END assertions
x - > _mPrev = position . mCurrent - > _mPrev ;
x - > _mNext = position . mCurrent ;
position . mCurrent - > _mPrev - > _mNext = x ;
position . mCurrent - > _mPrev = x ;
return - - position ;
}
// inserts x after position
iterator after_insert ( iterator position , pointer x )
{
// use |mCurrent| to prevent DEBUG_PASS_END assertions
x - > _mNext = position . mCurrent - > _mNext ;
x - > _mPrev = position . mCurrent ;
position . mCurrent - > _mNext - > _mPrev = x ;
position . mCurrent - > _mNext = x ;
return + + position ;
}
// returns iterator pointing to after the element
iterator erase ( iterator position )
// NOTE: leaves dangling next/prev pointers
{
position - > _mPrev - > _mNext = position - > _mNext ;
position - > _mNext - > _mPrev = position - > _mPrev ;
return + + position ;
}
void swap ( self_type & y )
{
link_type tmp ( y . mLink ) ;
y . mLink = mLink ;
mLink = tmp ;
}
void clear ( )
// NOTE: leaves dangling next/prev pointers
{
mLink . _mNext = & mLink ;
mLink . _mPrev = & mLink ;
}
// inserts the conts of x before position and makes x empty
void splice ( iterator position , self_type & x )
{
// use |mCurrent| to prevent DEBUG_PASS_END assertions
position . mCurrent - > _mPrev - > _mNext = x . mLink . _mNext ;
x . mLink . _mNext - > _mPrev = position . mCurrent - > _mPrev ;
x . mLink . _mPrev - > _mNext = position . mCurrent ;
position . mCurrent - > _mPrev = x . mLink . _mPrev ;
x . clear ( ) ;
}
// Inserts element *i from list x before position and removes
// it from x.
void splice ( iterator position , self_type & x , iterator i )
{
NS_ASSERTION ( ! x . empty ( ) , " Can't insert from empty list. " ) ;
NS_ASSERTION ( position ! = i & & position . mCurrent ! = i - > _mNext ,
" We don't check for this case. " ) ;
// remove from |x|
i - > _mPrev - > _mNext = i - > _mNext ;
i - > _mNext - > _mPrev = i - > _mPrev ;
// use |mCurrent| to prevent DEBUG_PASS_END assertions
// link into |this|, before-side
i - > _mPrev = position . mCurrent - > _mPrev ;
position . mCurrent - > _mPrev - > _mNext = i . get ( ) ;
// link into |this|, after-side
i - > _mNext = position . mCurrent ;
position . mCurrent - > _mPrev = i . get ( ) ;
}
// Inserts elements in [|first|, |last|), which are in |x|,
// into |this| before |position| and removes them from |x|.
void splice ( iterator position , self_type & x , iterator first ,
iterator last )
{
NS_ASSERTION ( ! x . empty ( ) , " Can't insert from empty list. " ) ;
if ( first = = last )
return ;
- - last ; // so we now want to move [first, last]
// remove from |x|
first - > _mPrev - > _mNext = last - > _mNext ;
last - > _mNext - > _mPrev = first - > _mPrev ;
// use |mCurrent| to prevent DEBUG_PASS_END assertions
// link into |this|, before-side
first - > _mPrev = position . mCurrent - > _mPrev ;
position . mCurrent - > _mPrev - > _mNext = first . get ( ) ;
// link into |this|, after-side
last - > _mNext = position . mCurrent ;
position . mCurrent - > _mPrev = last . get ( ) ;
}
} ;
// Many of these implementations of operator= don't work yet. I don't
// know why.
2007-08-02 15:43:14 -07:00
# ifdef DEBUG
2007-03-22 10:30:00 -07:00
// NOTE: ASSIGN_FROM is meant to be used *only* as the entire body
// of a function and therefore lacks PR_{BEGIN,END}_MACRO
# define ASSIGN_FROM(other_) \
mCurrent = other_ . mCurrent ; \
mListLink = other_ . mListLink ; \
return * this ;
# else /* !NS_LINELIST_DEBUG_PASS_END */
# define ASSIGN_FROM(other_) \
mCurrent = other_ . mCurrent ; \
return * this ;
# endif /* !NS_LINELIST_DEBUG_PASS_END */
inline
nsLineList_iterator &
nsLineList_iterator : : operator = ( const nsLineList_iterator & aOther )
{
ASSIGN_FROM ( aOther )
}
inline
nsLineList_iterator &
nsLineList_iterator : : operator = ( const nsLineList_reverse_iterator & aOther )
{
ASSIGN_FROM ( aOther )
}
inline
nsLineList_reverse_iterator &
nsLineList_reverse_iterator : : operator = ( const nsLineList_iterator & aOther )
{
ASSIGN_FROM ( aOther )
}
inline
nsLineList_reverse_iterator &
nsLineList_reverse_iterator : : operator = ( const nsLineList_reverse_iterator & aOther )
{
ASSIGN_FROM ( aOther )
}
inline
nsLineList_const_iterator &
nsLineList_const_iterator : : operator = ( const nsLineList_iterator & aOther )
{
ASSIGN_FROM ( aOther )
}
inline
nsLineList_const_iterator &
nsLineList_const_iterator : : operator = ( const nsLineList_reverse_iterator & aOther )
{
ASSIGN_FROM ( aOther )
}
inline
nsLineList_const_iterator &
nsLineList_const_iterator : : operator = ( const nsLineList_const_iterator & aOther )
{
ASSIGN_FROM ( aOther )
}
inline
nsLineList_const_iterator &
nsLineList_const_iterator : : operator = ( const nsLineList_const_reverse_iterator & aOther )
{
ASSIGN_FROM ( aOther )
}
inline
nsLineList_const_reverse_iterator &
nsLineList_const_reverse_iterator : : operator = ( const nsLineList_iterator & aOther )
{
ASSIGN_FROM ( aOther )
}
inline
nsLineList_const_reverse_iterator &
nsLineList_const_reverse_iterator : : operator = ( const nsLineList_reverse_iterator & aOther )
{
ASSIGN_FROM ( aOther )
}
inline
nsLineList_const_reverse_iterator &
nsLineList_const_reverse_iterator : : operator = ( const nsLineList_const_iterator & aOther )
{
ASSIGN_FROM ( aOther )
}
inline
nsLineList_const_reverse_iterator &
nsLineList_const_reverse_iterator : : operator = ( const nsLineList_const_reverse_iterator & aOther )
{
ASSIGN_FROM ( aOther )
}
//----------------------------------------------------------------------
class nsLineIterator : public nsILineIteratorNavigator {
public :
nsLineIterator ( ) ;
virtual ~ nsLineIterator ( ) ;
NS_DECL_ISUPPORTS
NS_IMETHOD GetNumLines ( PRInt32 * aResult ) ;
NS_IMETHOD GetDirection ( PRBool * aIsRightToLeft ) ;
NS_IMETHOD GetLine ( PRInt32 aLineNumber ,
nsIFrame * * aFirstFrameOnLine ,
PRInt32 * aNumFramesOnLine ,
nsRect & aLineBounds ,
PRUint32 * aLineFlags ) ;
NS_IMETHOD FindLineContaining ( nsIFrame * aFrame ,
PRInt32 * aLineNumberResult ) ;
NS_IMETHOD FindLineAt ( nscoord aY ,
PRInt32 * aLineNumberResult ) ;
NS_IMETHOD FindFrameAt ( PRInt32 aLineNumber ,
nscoord aX ,
nsIFrame * * aFrameFound ,
PRBool * aXIsBeforeFirstFrame ,
PRBool * aXIsAfterLastFrame ) ;
NS_IMETHOD GetNextSiblingOnLine ( nsIFrame * & aFrame , PRInt32 aLineNumber ) ;
# ifdef IBMBIDI
NS_IMETHOD CheckLineOrder ( PRInt32 aLine ,
PRBool * aIsReordered ,
nsIFrame * * aFirstVisual ,
nsIFrame * * aLastVisual ) ;
# endif
nsresult Init ( nsLineList & aLines , PRBool aRightToLeft ) ;
protected :
PRInt32 NumLines ( ) const {
return mNumLines ;
}
nsLineBox * CurrentLine ( ) {
return mLines [ mIndex ] ;
}
nsLineBox * PrevLine ( ) {
if ( 0 = = mIndex ) {
return nsnull ;
}
return mLines [ - - mIndex ] ;
}
nsLineBox * NextLine ( ) {
if ( mIndex > = mNumLines - 1 ) {
return nsnull ;
}
return mLines [ + + mIndex ] ;
}
nsLineBox * LineAt ( PRInt32 aIndex ) {
if ( ( aIndex < 0 ) | | ( aIndex > = mNumLines ) ) {
return nsnull ;
}
return mLines [ aIndex ] ;
}
nsLineBox * * mLines ;
PRInt32 mIndex ;
PRInt32 mNumLines ;
PRPackedBool mRightToLeft ;
} ;
# endif /* nsLineBox_h___ */