2001-09-28 20:14:13 +00:00
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2001-10-25 01:08:40 +00:00
// vim:cindent:ts=2:et:sw=2:
2001-09-28 20:14:13 +00:00
/* ***** BEGIN LICENSE BLOCK *****
2004-04-18 14:30:37 +00:00
* Version : MPL 1.1 / GPL 2.0 / LGPL 2.1
1998-12-01 16:13:49 +00:00
*
2004-04-18 14:30:37 +00:00
* 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/
1998-12-01 16:13:49 +00:00
*
2001-09-28 20:14:13 +00:00
* 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 .
1998-12-01 16:13:49 +00:00
*
* The Original Code is Mozilla Communicator client code .
*
2004-04-18 14:30:37 +00:00
* The Initial Developer of the Original Code is
2001-09-28 20:14:13 +00:00
* Netscape Communications Corporation .
* Portions created by the Initial Developer are Copyright ( C ) 1998
* the Initial Developer . All Rights Reserved .
1999-11-06 03:40:37 +00:00
*
2001-09-28 20:14:13 +00:00
* Contributor ( s ) :
2003-01-01 23:53:20 +00:00
* L . David Baron < dbaron @ dbaron . org >
2001-09-28 20:14:13 +00:00
*
* Alternatively , the contents of this file may be used under the terms of
2004-04-18 14:30:37 +00:00
* 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 " ) ,
2001-09-28 20:14:13 +00:00
* 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
2004-04-18 14:30:37 +00:00
* use your version of this file under the terms of the MPL , indicate your
2001-09-28 20:14:13 +00:00
* 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
2004-04-18 14:30:37 +00:00
* the terms of any one of the MPL , the GPL or the LGPL .
2001-09-28 20:14:13 +00:00
*
* * * * * * END LICENSE BLOCK * * * * * */
1998-12-01 16:13:49 +00:00
# ifndef nsLineBox_h___
# define nsLineBox_h___
# include "nsVoidArray.h"
# include "nsPlaceholderFrame.h"
1999-05-13 00:54:28 +00:00
# include "nsILineIterator.h"
1998-12-01 16:13:49 +00:00
2001-10-26 05:06:07 +00:00
class nsSpaceManager ;
1998-12-01 16:13:49 +00:00
class nsLineBox ;
2003-10-13 21:51:02 +00:00
class nsFloatCache ;
class nsFloatCacheList ;
class nsFloatCacheFreeList ;
1999-09-15 00:28:10 +00:00
2003-10-13 21:51:02 +00:00
// State cached after reflowing a float. This state is used during
// incremental reflow when we avoid reflowing a float.
class nsFloatCache {
1999-09-15 00:28:10 +00:00
public :
2003-10-13 21:51:02 +00:00
nsFloatCache ( ) ;
2000-12-16 18:56:06 +00:00
# ifdef NS_BUILD_REFCNT_LOGGING
2003-10-13 21:51:02 +00:00
~ nsFloatCache ( ) ;
1999-10-08 20:41:19 +00:00
# else
2003-10-13 21:51:02 +00:00
~ nsFloatCache ( ) { }
1999-10-08 20:41:19 +00:00
# endif
1999-09-15 00:28:10 +00:00
2003-10-13 21:51:02 +00:00
nsFloatCache * Next ( ) const { return mNext ; }
1999-09-15 00:28:10 +00:00
nsPlaceholderFrame * mPlaceholder ; // nsPlaceholderFrame
2003-10-13 21:51:02 +00:00
// This will be true if the float was placed on the current line
1999-09-15 00:28:10 +00:00
// instead of below the current line.
2003-10-13 21:51:02 +00:00
PRBool mIsCurrentLineFloat ;
1999-09-15 00:28:10 +00:00
nsMargin mMargins ; // computed margins
nsMargin mOffsets ; // computed offsets (relative pos)
2003-10-13 21:51:02 +00:00
// Region in the spacemanager impacted by this float; the
1999-09-15 00:28:10 +00:00
// coordinates are relative to the containing block frame. The
2003-10-13 21:51:02 +00:00
// region includes the margins around the float, but doesn't
1999-09-15 00:28:10 +00:00
// include the relative offsets.
nsRect mRegion ;
2003-10-13 21:51:02 +00:00
// Combined area for the float. This will not include the margins
// for the float. Like mRegion, the coordinates are relative to
1999-09-15 00:28:10 +00:00
// the containing block frame.
nsRect mCombinedArea ;
2003-10-13 21:51:02 +00:00
// The float's max-element-width.
2003-02-22 16:19:31 +00:00
nscoord mMaxElementWidth ;
1999-09-15 00:28:10 +00:00
protected :
2003-10-13 21:51:02 +00:00
nsFloatCache * mNext ;
1999-09-15 00:28:10 +00:00
2003-10-13 21:51:02 +00:00
friend class nsFloatCacheList ;
friend class nsFloatCacheFreeList ;
1999-09-15 00:28:10 +00:00
} ;
//----------------------------------------
2003-10-13 21:51:02 +00:00
class nsFloatCacheList {
1999-09-15 00:28:10 +00:00
public :
2003-10-13 21:51:02 +00:00
nsFloatCacheList ( ) : mHead ( nsnull ) { }
~ nsFloatCacheList ( ) ;
1999-09-15 00:28:10 +00:00
PRBool IsEmpty ( ) const {
return nsnull = = mHead ;
}
PRBool NotEmpty ( ) const {
return nsnull ! = mHead ;
}
2003-10-13 21:51:02 +00:00
nsFloatCache * Head ( ) const {
1999-09-15 00:28:10 +00:00
return mHead ;
}
2003-10-13 21:51:02 +00:00
nsFloatCache * Tail ( ) const ;
1999-09-15 00:28:10 +00:00
2003-10-13 21:51:02 +00:00
nsFloatCache * Find ( nsIFrame * aOutOfFlowFrame ) ;
1999-09-15 00:28:10 +00:00
2003-10-13 21:51:02 +00:00
void Remove ( nsFloatCache * aElement ) ;
1999-09-15 00:28:10 +00:00
2003-10-13 21:51:02 +00:00
void Append ( nsFloatCacheFreeList & aList ) ;
1999-09-15 00:28:10 +00:00
protected :
2003-10-13 21:51:02 +00:00
nsFloatCache * mHead ;
1999-09-15 00:28:10 +00:00
2003-10-13 21:51:02 +00:00
friend class nsFloatCacheFreeList ;
1999-09-15 00:28:10 +00:00
} ;
//---------------------------------------
2003-10-13 21:51:02 +00:00
class nsFloatCacheFreeList : public nsFloatCacheList {
1999-09-15 00:28:10 +00:00
public :
2003-10-13 21:51:02 +00:00
nsFloatCacheFreeList ( ) : mTail ( nsnull ) { }
~ nsFloatCacheFreeList ( ) { }
1999-09-15 00:28:10 +00:00
2003-10-13 21:51:02 +00:00
// Steal away aList's nsFloatCache objects and put them on this
1999-09-15 00:28:10 +00:00
// free-list.
2003-10-13 21:51:02 +00:00
void Append ( nsFloatCacheList & aList ) ;
1999-09-15 00:28:10 +00:00
2003-10-13 21:51:02 +00:00
void Append ( nsFloatCache * aFloatCache ) ;
1999-09-15 00:28:10 +00:00
2003-10-13 21:51:02 +00:00
// Allocate a new nsFloatCache object
nsFloatCache * Alloc ( ) ;
1999-09-15 00:28:10 +00:00
protected :
2003-10-13 21:51:02 +00:00
nsFloatCache * mTail ;
1999-09-15 00:28:10 +00:00
2003-10-13 21:51:02 +00:00
friend class nsFloatCacheList ;
1999-09-15 00:28:10 +00:00
} ;
//----------------------------------------------------------------------
1999-10-14 23:10:03 +00:00
# define LINE_MAX_BREAK_TYPE ((1 << 4) - 1)
2000-09-11 20:46:44 +00:00
# define LINE_MAX_CHILD_COUNT ((1 << 20) - 1)
1999-10-14 23:10:03 +00:00
# if NS_STYLE_CLEAR_LAST_VALUE > 15
need to rearrange the mBits bitfield ;
# endif
2000-03-12 03:00:51 +00:00
// Funtion to create a line box
nsLineBox * NS_NewLineBox ( nsIPresShell * aPresShell , nsIFrame * aFrame ,
PRInt32 aCount , PRBool aIsBlock ) ;
2001-10-25 01:08:40 +00:00
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
} ;
1998-12-01 16:13:49 +00:00
/**
* 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 .
*/
2001-10-25 01:08:40 +00:00
class nsLineBox : public nsLineLink {
2000-03-12 03:00:51 +00:00
private :
1999-10-12 23:24:22 +00:00
nsLineBox ( nsIFrame * aFrame , PRInt32 aCount , PRBool aIsBlock ) ;
~ nsLineBox ( ) ;
2000-03-12 03:00:51 +00:00
// Overloaded new operator. Uses an arena (which comes from the presShell)
// to perform the allocation.
2002-07-03 17:14:41 +00:00
void * operator new ( size_t sz , nsIPresShell * aPresShell ) CPP_THROW_NEW ;
2000-03-12 03:00:51 +00:00
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 ) ;
1999-10-12 23:24:22 +00:00
2000-03-12 03:00:51 +00:00
void Destroy ( nsIPresShell * aPresShell ) ;
1999-10-19 23:04:19 +00:00
1999-10-14 23:10:03 +00:00
// mBlock bit
1999-10-12 23:24:22 +00:00
PRBool IsBlock ( ) const {
return mFlags . mBlock ;
}
PRBool IsInline ( ) const {
return 0 = = mFlags . mBlock ;
}
1999-10-14 23:10:03 +00:00
// mDirty bit
void MarkDirty ( ) {
mFlags . mDirty = 1 ;
}
void ClearDirty ( ) {
mFlags . mDirty = 0 ;
}
PRBool IsDirty ( ) const {
return mFlags . mDirty ;
}
2001-10-25 01:08:40 +00:00
// mPreviousMarginDirty bit
void MarkPreviousMarginDirty ( ) {
mFlags . mPreviousMarginDirty = 1 ;
}
void ClearPreviousMarginDirty ( ) {
mFlags . mPreviousMarginDirty = 0 ;
}
PRBool IsPreviousMarginDirty ( ) const {
return mFlags . mPreviousMarginDirty ;
}
2004-11-25 14:51:00 +00:00
// mHasClearance bit
void SetHasClearance ( ) {
mFlags . mHasClearance = 1 ;
}
void ClearHasClearance ( ) {
mFlags . mHasClearance = 0 ;
}
PRBool HasClearance ( ) const {
return mFlags . mHasClearance ;
}
2003-10-13 21:51:02 +00:00
// mImpactedByFloat bit
void SetLineIsImpactedByFloat ( PRBool aValue ) {
2000-03-22 23:19:10 +00:00
NS_ASSERTION ( ( PR_FALSE = = aValue | | PR_TRUE = = aValue ) , " somebody is playing fast and loose with bools and bits! " ) ;
2003-10-13 21:51:02 +00:00
mFlags . mImpactedByFloat = aValue ;
1999-10-14 23:10:03 +00:00
}
2003-10-13 21:51:02 +00:00
PRBool IsImpactedByFloat ( ) const {
return mFlags . mImpactedByFloat ;
1999-10-14 23:10:03 +00:00
}
2000-01-03 04:32:13 +00:00
// mHasPercentageChild bit
1999-10-29 14:35:36 +00:00
void SetHasPercentageChild ( PRBool aOn ) {
2000-03-22 23:19:10 +00:00
NS_ASSERTION ( ( PR_FALSE = = aOn | | PR_TRUE = = aOn ) , " somebody is playing fast and loose with bools and bits! " ) ;
1999-10-29 14:35:36 +00:00
mFlags . mHasPercentageChild = aOn ;
}
PRBool HasPercentageChild ( ) const {
return mFlags . mHasPercentageChild ;
}
2000-01-03 04:32:13 +00:00
// mLineWrapped bit
void SetLineWrapped ( PRBool aOn ) {
2000-03-22 23:19:10 +00:00
NS_ASSERTION ( ( PR_FALSE = = aOn | | PR_TRUE = = aOn ) , " somebody is playing fast and loose with bools and bits! " ) ;
2000-01-03 04:32:13 +00:00
mFlags . mLineWrapped = aOn ;
}
PRBool IsLineWrapped ( ) const {
return mFlags . mLineWrapped ;
}
2000-08-24 04:26:43 +00:00
2000-09-11 20:46:44 +00:00
// mResizeReflowOptimizationDisabled bit
void DisableResizeReflowOptimization ( ) {
mFlags . mResizeReflowOptimizationDisabled = PR_TRUE ;
}
void EnableResizeReflowOptimization ( ) {
mFlags . mResizeReflowOptimizationDisabled = PR_FALSE ;
}
PRBool ResizeReflowOptimizationDisabled ( ) const {
return mFlags . mResizeReflowOptimizationDisabled ;
}
2000-01-03 04:32:13 +00:00
1999-10-14 23:10:03 +00:00
// mChildCount value
PRInt32 GetChildCount ( ) const {
return ( PRInt32 ) mFlags . mChildCount ;
}
void SetChildCount ( PRInt32 aNewCount ) {
2002-01-24 09:20:51 +00:00
if ( aNewCount < 0 ) {
NS_WARNING ( " negative child count " ) ;
1999-10-14 23:10:03 +00:00
aNewCount = 0 ;
}
if ( aNewCount > LINE_MAX_CHILD_COUNT ) {
aNewCount = LINE_MAX_CHILD_COUNT ;
}
mFlags . mChildCount = aNewCount ;
}
// mBreakType value
2004-11-25 14:51:00 +00:00
// 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 ;
1999-10-12 23:24:22 +00:00
}
2004-11-25 14:51:00 +00:00
PRBool HasBreakAfter ( ) const {
return ! IsBlock ( ) & & NS_STYLE_CLEAR_NONE ! = mFlags . mBreakType ;
2004-09-13 02:21:35 +00:00
}
2004-11-25 14:51:00 +00:00
void SetBreakTypeAfter ( PRUint8 aBreakType ) {
NS_ASSERTION ( ! IsBlock ( ) , " Only inlines have break-after " ) ;
NS_ASSERTION ( aBreakType < = LINE_MAX_BREAK_TYPE , " bad break type " ) ;
1999-10-12 23:24:22 +00:00
mFlags . mBreakType = aBreakType ;
}
2004-11-25 14:51:00 +00:00
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 ;
1999-10-12 23:24:22 +00:00
}
1998-12-01 16:13:49 +00:00
1999-10-14 23:10:03 +00:00
// mCarriedOutBottomMargin value
2001-10-25 01:08:40 +00:00
nsCollapsingMargin GetCarriedOutBottomMargin ( ) const ;
2004-09-18 14:39:07 +00:00
// Returns PR_TRUE if the margin changed
PRBool SetCarriedOutBottomMargin ( nsCollapsingMargin aValue ) ;
1999-10-14 23:10:03 +00:00
2003-10-13 21:51:02 +00:00
// mFloats
PRBool HasFloats ( ) const {
return ( IsInline ( ) & & mInlineData ) & & mInlineData - > mFloats . NotEmpty ( ) ;
1998-12-01 16:13:49 +00:00
}
2003-10-13 21:51:02 +00:00
nsFloatCache * GetFirstFloat ( ) ;
void FreeFloats ( nsFloatCacheFreeList & aFreeList ) ;
void AppendFloats ( nsFloatCacheFreeList & aFreeList ) ;
PRBool RemoveFloat ( nsIFrame * aFrame ) ;
1998-12-01 16:13:49 +00:00
2002-11-21 15:20:20 +00:00
// 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').
1999-10-14 23:10:03 +00:00
void SetCombinedArea ( const nsRect & aCombinedArea ) ;
2004-01-22 15:06:25 +00:00
nsRect GetCombinedArea ( ) {
return mData ? mData - > mCombinedArea : mBounds ;
}
1999-10-19 23:04:19 +00:00
PRBool CombinedAreaIntersects ( const nsRect & aDamageRect ) {
nsRect * ca = ( mData ? & mData - > mCombinedArea : & mBounds ) ;
return ! ( ( ca - > YMost ( ) < = aDamageRect . y ) | |
( ca - > y > = aDamageRect . YMost ( ) ) ) ;
}
1998-12-01 16:13:49 +00:00
1999-10-14 23:10:03 +00:00
void SlideBy ( nscoord aDY ) {
mBounds . y + = aDY ;
if ( mData ) {
mData - > mCombinedArea . y + = aDY ;
}
}
2002-12-11 04:00:18 +00:00
/**
* 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 ; }
1999-10-14 23:10:03 +00:00
nscoord GetHeight ( ) const {
return mBounds . height ;
}
1998-12-01 16:13:49 +00:00
2004-07-31 23:15:21 +00:00
static void DeleteLineList ( nsPresContext * aPresContext , nsLineList & aLines ) ;
1998-12-01 16:13:49 +00:00
2001-10-25 01:08:40 +00:00
// search from beginning to end
// XXX Should switch to API below
static nsLineBox * FindLineContaining ( nsLineList & aLines , nsIFrame * aFrame ,
1999-04-20 21:52:22 +00:00
PRInt32 * aFrameIndexInLine ) ;
1998-12-01 16:13:49 +00:00
2001-10-25 01:08:40 +00:00
// 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 ) ;
1999-11-01 22:12:45 +00:00
# ifdef DEBUG
2001-10-25 01:08:40 +00:00
char * StateToString ( char * aBuf , PRInt32 aBufSize ) const ;
2005-09-06 21:34:50 +00:00
void List ( FILE * out , PRInt32 aIndent ) const ;
1999-11-01 22:12:45 +00:00
# endif
1998-12-01 16:13:49 +00:00
nsIFrame * LastChild ( ) const ;
PRBool IsLastChild ( nsIFrame * aFrame ) const ;
1999-04-20 21:52:22 +00:00
PRInt32 IndexOf ( nsIFrame * aFrame ) const ;
PRBool Contains ( nsIFrame * aFrame ) const {
return IndexOf ( aFrame ) > = 0 ;
}
1998-12-01 16:13:49 +00:00
2001-10-25 01:08:40 +00:00
// whether the line box is "logically" empty (just like nsIFrame::IsEmpty)
2003-11-10 23:36:06 +00:00
PRBool IsEmpty ( ) const ;
2001-10-25 01:08:40 +00:00
2004-11-24 13:22:10 +00:00
// 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 the block.
PRBool CachedIsEmpty ( ) ;
void InvalidateCachedIsEmpty ( ) {
mFlags . mEmptyCacheValid = PR_FALSE ;
}
// For debugging purposes
PRBool IsValidCachedIsEmpty ( ) {
return mFlags . mEmptyCacheValid ;
}
1999-10-02 02:51:03 +00:00
# ifdef DEBUG
1999-10-19 23:04:19 +00:00
static PRInt32 GetCtorCount ( ) ;
1999-10-02 02:51:03 +00:00
# endif
1998-12-01 16:13:49 +00:00
nsIFrame * mFirstChild ;
1999-10-14 23:10:03 +00:00
nsRect mBounds ;
1999-08-28 00:39:55 +00:00
nscoord mMaxElementWidth ; // width part of max-element-size
1999-12-30 04:15:45 +00:00
nscoord mMaximumWidth ; // maximum width (needed for incremental reflow of tables)
2005-06-20 03:42:19 +00:00
// includes the left border/padding but not the right
1999-10-12 23:24:22 +00:00
struct FlagBits {
PRUint32 mDirty : 1 ;
2001-10-25 01:08:40 +00:00
PRUint32 mPreviousMarginDirty : 1 ;
2004-11-25 14:51:00 +00:00
PRUint32 mHasClearance : 1 ;
1999-10-12 23:24:22 +00:00
PRUint32 mBlock : 1 ;
2003-10-13 21:51:02 +00:00
PRUint32 mImpactedByFloat : 1 ;
1999-10-29 14:35:36 +00:00
PRUint32 mHasPercentageChild : 1 ;
2000-01-03 04:32:13 +00:00
PRUint32 mLineWrapped : 1 ;
2001-10-25 01:08:40 +00: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
2004-11-24 13:22:10 +00:00
PRUint32 mEmptyCacheValid : 1 ;
PRUint32 mEmptyCacheState : 1 ;
1999-10-14 23:10:03 +00:00
PRUint32 mBreakType : 4 ;
2004-11-25 14:51:00 +00:00
PRUint32 mChildCount : 18 ;
1999-10-14 23:10:03 +00:00
} ;
struct ExtraData {
ExtraData ( const nsRect & aBounds ) : mCombinedArea ( aBounds ) {
}
nsRect mCombinedArea ;
} ;
struct ExtraBlockData : public ExtraData {
2001-10-25 01:08:40 +00:00
ExtraBlockData ( const nsRect & aBounds )
: ExtraData ( aBounds ) ,
mCarriedOutBottomMargin ( )
{
1999-10-14 23:10:03 +00:00
}
2001-10-25 01:08:40 +00:00
nsCollapsingMargin mCarriedOutBottomMargin ;
1999-10-14 23:10:03 +00:00
} ;
1999-10-12 23:24:22 +00:00
1999-10-14 23:10:03 +00:00
struct ExtraInlineData : public ExtraData {
ExtraInlineData ( const nsRect & aBounds ) : ExtraData ( aBounds ) {
}
2003-10-13 21:51:02 +00:00
nsFloatCacheList mFloats ;
1999-10-12 23:24:22 +00:00
} ;
protected :
2002-12-11 04:00:18 +00:00
nscoord mAscent ; // see |SetAscent| / |GetAscent|
1999-10-12 23:24:22 +00:00
union {
PRUint32 mAllFlags ;
FlagBits mFlags ;
} ;
1999-10-14 23:10:03 +00:00
union {
ExtraData * mData ;
ExtraBlockData * mBlockData ;
ExtraInlineData * mInlineData ;
} ;
1999-10-19 23:04:19 +00:00
void Cleanup ( ) ;
1999-10-14 23:10:03 +00:00
void MaybeFreeData ( ) ;
1998-12-01 16:13:49 +00:00
} ;
2001-10-25 01:08:40 +00:00
# ifdef DEBUG
# define NS_LINELIST_DEBUG_PASS_END
# else
# undef NS_LINELIST_DEBUG_PASS_END
# endif
/**
* 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 ;
// Auto generated default constructor OK.
// 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 * ( )
{
# ifdef NS_LINELIST_DEBUG_PASS_END
NS_ASSERTION ( mCurrent ! = mListLink , " running past end " ) ;
# endif
return * NS_STATIC_CAST ( pointer , mCurrent ) ;
}
pointer operator - > ( )
{
# ifdef NS_LINELIST_DEBUG_PASS_END
NS_ASSERTION ( mCurrent ! = mListLink , " running past end " ) ;
# endif
return NS_STATIC_CAST ( pointer , mCurrent ) ;
}
pointer get ( )
{
# ifdef NS_LINELIST_DEBUG_PASS_END
NS_ASSERTION ( mCurrent ! = mListLink , " running past end " ) ;
# endif
return NS_STATIC_CAST ( pointer , mCurrent ) ;
}
operator pointer ( )
{
# ifdef NS_LINELIST_DEBUG_PASS_END
NS_ASSERTION ( mCurrent ! = mListLink , " running past end " ) ;
# endif
return NS_STATIC_CAST ( pointer , mCurrent ) ;
}
const_reference operator * ( ) const
{
# ifdef NS_LINELIST_DEBUG_PASS_END
NS_ASSERTION ( mCurrent ! = mListLink , " running past end " ) ;
# endif
return * NS_STATIC_CAST ( const_pointer , mCurrent ) ;
}
const_pointer operator - > ( ) const
{
# ifdef NS_LINELIST_DEBUG_PASS_END
NS_ASSERTION ( mCurrent ! = mListLink , " running past end " ) ;
# endif
return NS_STATIC_CAST ( const_pointer , mCurrent ) ;
}
# ifndef __MWERKS__
operator const_pointer ( ) const
{
# ifdef NS_LINELIST_DEBUG_PASS_END
NS_ASSERTION ( mCurrent ! = mListLink , " running past end " ) ;
# endif
return NS_STATIC_CAST ( const_pointer , mCurrent ) ;
}
# 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 ;
}
2001-10-25 06:34:10 +00:00
// Passing by value rather than by reference and reference to const
// to keep AIX happy.
// XXX Should add assertions that |mListLink| is the same for both.
PRBool operator = = ( const iterator_self_type aOther ) const
2001-10-25 01:08:40 +00:00
{ return mCurrent = = aOther . mCurrent ; }
2001-10-25 06:34:10 +00:00
PRBool operator ! = ( const iterator_self_type aOther ) const
2001-10-25 01:08:40 +00:00
{ return mCurrent ! = aOther . mCurrent ; }
2001-10-25 06:34:10 +00:00
PRBool operator = = ( const iterator_self_type aOther )
2001-10-25 01:08:40 +00:00
{ return mCurrent = = aOther . mCurrent ; }
2001-10-25 06:34:10 +00:00
PRBool operator ! = ( const iterator_self_type aOther )
2001-10-25 01:08:40 +00:00
{ return mCurrent ! = aOther . mCurrent ; }
private :
link_type * mCurrent ;
# ifdef NS_LINELIST_DEBUG_PASS_END
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 ;
// Auto generated default constructor OK.
// 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 * ( )
{
# ifdef NS_LINELIST_DEBUG_PASS_END
NS_ASSERTION ( mCurrent ! = mListLink , " running past end " ) ;
# endif
return * NS_STATIC_CAST ( pointer , mCurrent ) ;
}
pointer operator - > ( )
{
# ifdef NS_LINELIST_DEBUG_PASS_END
NS_ASSERTION ( mCurrent ! = mListLink , " running past end " ) ;
# endif
return NS_STATIC_CAST ( pointer , mCurrent ) ;
}
pointer get ( )
{
# ifdef NS_LINELIST_DEBUG_PASS_END
NS_ASSERTION ( mCurrent ! = mListLink , " running past end " ) ;
# endif
return NS_STATIC_CAST ( pointer , mCurrent ) ;
}
operator pointer ( )
{
# ifdef NS_LINELIST_DEBUG_PASS_END
NS_ASSERTION ( mCurrent ! = mListLink , " running past end " ) ;
# endif
return NS_STATIC_CAST ( pointer , mCurrent ) ;
}
const_reference operator * ( ) const
{
# ifdef NS_LINELIST_DEBUG_PASS_END
NS_ASSERTION ( mCurrent ! = mListLink , " running past end " ) ;
# endif
return * NS_STATIC_CAST ( const_pointer , mCurrent ) ;
}
const_pointer operator - > ( ) const
{
# ifdef NS_LINELIST_DEBUG_PASS_END
NS_ASSERTION ( mCurrent ! = mListLink , " running past end " ) ;
# endif
return NS_STATIC_CAST ( const_pointer , mCurrent ) ;
}
# ifndef __MWERKS__
operator const_pointer ( ) const
{
# ifdef NS_LINELIST_DEBUG_PASS_END
NS_ASSERTION ( mCurrent ! = mListLink , " running past end " ) ;
# endif
return NS_STATIC_CAST ( const_pointer , mCurrent ) ;
}
# endif /* !__MWERKS__ */
2001-10-25 06:34:10 +00:00
// Passing by value rather than by reference and reference to const
// to keep AIX happy.
PRBool operator = = ( const iterator_self_type aOther ) const
2001-10-25 01:08:40 +00:00
{ return mCurrent = = aOther . mCurrent ; }
2001-10-25 06:34:10 +00:00
PRBool operator ! = ( const iterator_self_type aOther ) const
2001-10-25 01:08:40 +00:00
{ return mCurrent ! = aOther . mCurrent ; }
2001-10-25 06:34:10 +00:00
PRBool operator = = ( const iterator_self_type aOther )
2001-10-25 01:08:40 +00:00
{ return mCurrent = = aOther . mCurrent ; }
2001-10-25 06:34:10 +00:00
PRBool operator ! = ( const iterator_self_type aOther )
2001-10-25 01:08:40 +00:00
{ return mCurrent ! = aOther . mCurrent ; }
private :
link_type * mCurrent ;
# ifdef NS_LINELIST_DEBUG_PASS_END
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 ;
// Auto generated default constructor OK.
// 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
{
# ifdef NS_LINELIST_DEBUG_PASS_END
NS_ASSERTION ( mCurrent ! = mListLink , " running past end " ) ;
# endif
return * NS_STATIC_CAST ( const_pointer , mCurrent ) ;
}
const_pointer operator - > ( ) const
{
# ifdef NS_LINELIST_DEBUG_PASS_END
NS_ASSERTION ( mCurrent ! = mListLink , " running past end " ) ;
# endif
return NS_STATIC_CAST ( const_pointer , mCurrent ) ;
}
const_pointer get ( ) const
{
# ifdef NS_LINELIST_DEBUG_PASS_END
NS_ASSERTION ( mCurrent ! = mListLink , " running past end " ) ;
# endif
return NS_STATIC_CAST ( const_pointer , mCurrent ) ;
}
# ifndef __MWERKS__
operator const_pointer ( ) const
{
# ifdef NS_LINELIST_DEBUG_PASS_END
NS_ASSERTION ( mCurrent ! = mListLink , " running past end " ) ;
# endif
return NS_STATIC_CAST ( const_pointer , mCurrent ) ;
}
# 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 ;
}
2001-10-25 06:34:10 +00:00
// Passing by value rather than by reference and reference to const
// to keep AIX happy.
PRBool operator = = ( const iterator_self_type aOther ) const
2001-10-25 01:08:40 +00:00
{ return mCurrent = = aOther . mCurrent ; }
2001-10-25 06:34:10 +00:00
PRBool operator ! = ( const iterator_self_type aOther ) const
2001-10-25 01:08:40 +00:00
{ return mCurrent ! = aOther . mCurrent ; }
2001-10-25 06:34:10 +00:00
PRBool operator = = ( const iterator_self_type aOther )
2001-10-25 01:08:40 +00:00
{ return mCurrent = = aOther . mCurrent ; }
2001-10-25 06:34:10 +00:00
PRBool operator ! = ( const iterator_self_type aOther )
2001-10-25 01:08:40 +00:00
{ return mCurrent ! = aOther . mCurrent ; }
private :
const link_type * mCurrent ;
# ifdef NS_LINELIST_DEBUG_PASS_END
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 ;
// Auto generated default constructor OK.
// 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
{
# ifdef NS_LINELIST_DEBUG_PASS_END
NS_ASSERTION ( mCurrent ! = mListLink , " running past end " ) ;
# endif
return * NS_STATIC_CAST ( const_pointer , mCurrent ) ;
}
const_pointer operator - > ( ) const
{
# ifdef NS_LINELIST_DEBUG_PASS_END
NS_ASSERTION ( mCurrent ! = mListLink , " running past end " ) ;
# endif
return NS_STATIC_CAST ( const_pointer , mCurrent ) ;
}
const_pointer get ( ) const
{
# ifdef NS_LINELIST_DEBUG_PASS_END
NS_ASSERTION ( mCurrent ! = mListLink , " running past end " ) ;
# endif
return NS_STATIC_CAST ( const_pointer , mCurrent ) ;
}
# ifndef __MWERKS__
operator const_pointer ( ) const
{
# ifdef NS_LINELIST_DEBUG_PASS_END
NS_ASSERTION ( mCurrent ! = mListLink , " running past end " ) ;
# endif
return NS_STATIC_CAST ( const_pointer , mCurrent ) ;
}
# endif /* !__MWERKS__ */
2001-10-25 06:34:10 +00:00
// Passing by value rather than by reference and reference to const
// to keep AIX happy.
PRBool operator = = ( const iterator_self_type aOther ) const
2001-10-25 01:08:40 +00:00
{ return mCurrent = = aOther . mCurrent ; }
2001-10-25 06:34:10 +00:00
PRBool operator ! = ( const iterator_self_type aOther ) const
2001-10-25 01:08:40 +00:00
{ return mCurrent ! = aOther . mCurrent ; }
2001-10-25 06:34:10 +00:00
PRBool operator = = ( const iterator_self_type aOther )
2001-10-25 01:08:40 +00:00
{ return mCurrent = = aOther . mCurrent ; }
2001-10-25 06:34:10 +00:00
PRBool operator ! = ( const iterator_self_type aOther )
2001-10-25 01:08:40 +00:00
{ return mCurrent ! = aOther . mCurrent ; }
//private:
const link_type * mCurrent ;
# ifdef NS_LINELIST_DEBUG_PASS_END
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 ;
# ifdef NS_LINELIST_DEBUG_PASS_END
rv . mListLink = & mLink ;
# endif
return rv ;
}
iterator begin ( )
{
iterator rv ;
rv . mCurrent = mLink . _mNext ;
# ifdef NS_LINELIST_DEBUG_PASS_END
rv . mListLink = & mLink ;
# endif
return rv ;
}
2004-03-07 18:04:24 +00:00
iterator begin ( nsLineBox * aLine )
{
iterator rv ;
rv . mCurrent = aLine ;
# ifdef NS_LINELIST_DEBUG_PASS_END
rv . mListLink = & mLink ;
# endif
return rv ;
}
2001-10-25 01:08:40 +00:00
const_iterator end ( ) const
{
const_iterator rv ;
rv . mCurrent = & mLink ;
# ifdef NS_LINELIST_DEBUG_PASS_END
rv . mListLink = & mLink ;
# endif
return rv ;
}
iterator end ( )
{
iterator rv ;
rv . mCurrent = & mLink ;
# ifdef NS_LINELIST_DEBUG_PASS_END
rv . mListLink = & mLink ;
# endif
return rv ;
}
const_reverse_iterator rbegin ( ) const
{
const_reverse_iterator rv ;
rv . mCurrent = mLink . _mPrev ;
# ifdef NS_LINELIST_DEBUG_PASS_END
rv . mListLink = & mLink ;
# endif
return rv ;
}
reverse_iterator rbegin ( )
{
reverse_iterator rv ;
rv . mCurrent = mLink . _mPrev ;
# ifdef NS_LINELIST_DEBUG_PASS_END
rv . mListLink = & mLink ;
# endif
return rv ;
}
const_reverse_iterator rend ( ) const
{
const_reverse_iterator rv ;
rv . mCurrent = & mLink ;
# ifdef NS_LINELIST_DEBUG_PASS_END
rv . mListLink = & mLink ;
# endif
return rv ;
}
reverse_iterator rend ( )
{
reverse_iterator rv ;
rv . mCurrent = & mLink ;
# ifdef NS_LINELIST_DEBUG_PASS_END
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 " ) ;
return NS_STATIC_CAST ( pointer , mLink . _mNext ) ;
}
const_pointer front ( ) const
{
NS_ASSERTION ( ! empty ( ) , " no element to return " ) ;
return NS_STATIC_CAST ( const_pointer , mLink . _mNext ) ;
}
pointer back ( )
{
NS_ASSERTION ( ! empty ( ) , " no element to return " ) ;
return NS_STATIC_CAST ( pointer , mLink . _mPrev ) ;
}
const_pointer back ( ) const
{
NS_ASSERTION ( ! empty ( ) , " no element to return " ) ;
return NS_STATIC_CAST ( const_pointer , mLink . _mPrev ) ;
}
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. " ) ;
2001-10-25 20:19:32 +00:00
NS_ASSERTION ( position ! = i & & position . mCurrent ! = i - > _mNext ,
2001-10-25 01:08:40 +00:00
" 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.
# ifdef NS_LINELIST_DEBUG_PASS_END
// 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 )
}
1999-05-10 22:28:49 +00:00
//----------------------------------------------------------------------
2000-05-16 08:11:14 +00:00
class nsLineIterator : public nsILineIteratorNavigator {
1999-05-13 00:54:28 +00:00
public :
1999-05-10 22:28:49 +00:00
nsLineIterator ( ) ;
1999-05-13 00:54:28 +00:00
virtual ~ nsLineIterator ( ) ;
NS_DECL_ISUPPORTS
NS_IMETHOD GetNumLines ( PRInt32 * aResult ) ;
NS_IMETHOD GetDirection ( PRBool * aIsRightToLeft ) ;
NS_IMETHOD GetLine ( PRInt32 aLineNumber ,
nsIFrame * * aFirstFrameOnLine ,
PRInt32 * aNumFramesOnLine ,
1999-10-12 23:24:22 +00:00
nsRect & aLineBounds ,
PRUint32 * aLineFlags ) ;
1999-05-13 00:54:28 +00:00
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 ) ;
2000-06-16 22:28:10 +00:00
NS_IMETHOD GetNextSiblingOnLine ( nsIFrame * & aFrame , PRInt32 aLineNumber ) ;
2001-03-09 03:29:00 +00:00
# ifdef IBMBIDI
NS_IMETHOD CheckLineOrder ( PRInt32 aLine ,
PRBool * aIsReordered ,
nsIFrame * * aFirstVisual ,
nsIFrame * * aLastVisual ) ;
# endif
2001-10-25 01:08:40 +00:00
nsresult Init ( nsLineList & aLines , PRBool aRightToLeft ) ;
1999-05-13 00:54:28 +00:00
protected :
1999-05-10 22:28:49 +00:00
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 ;
2000-09-11 20:46:44 +00:00
PRPackedBool mRightToLeft ;
1999-05-10 22:28:49 +00:00
} ;
1998-12-01 16:13:49 +00:00
# endif /* nsLineBox_h___ */