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:
2012-05-21 04:12:37 -07:00
/* This Source Code Form is subject to the terms of the Mozilla Public
* License , v . 2.0 . If a copy of the MPL was not distributed with this
* file , You can obtain one at http : //mozilla.org/MPL/2.0/. */
2007-03-22 10:30:00 -07:00
/* representation of one line within a block frame, a CSS line box */
# ifndef nsLineBox_h___
# define nsLineBox_h___
2011-11-20 22:21:16 -08:00
# include "mozilla/Attributes.h"
2012-10-26 06:32:10 -07:00
# include "mozilla/Likely.h"
2011-11-20 22:21:16 -08:00
2007-03-22 10:30:00 -07:00
# include "nsILineIterator.h"
2009-08-31 11:25:35 -07:00
# include "nsIFrame.h"
2013-01-15 04:22:03 -08:00
# include <algorithm>
2007-03-22 10:30:00 -07:00
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 ; }
2009-08-31 11:25:35 -07:00
nsIFrame * mFloat ; // floating frame
2007-03-22 10:30:00 -07:00
protected :
nsFloatCache * mNext ;
friend class nsFloatCacheList ;
friend class nsFloatCacheFreeList ;
} ;
//----------------------------------------
class nsFloatCacheList {
public :
# ifdef NS_BUILD_REFCNT_LOGGING
nsFloatCacheList ( ) ;
# else
2012-07-30 07:20:58 -07:00
nsFloatCacheList ( ) : mHead ( nullptr ) { }
2007-03-22 10:30:00 -07:00
# endif
~ nsFloatCacheList ( ) ;
2011-09-28 23:19:26 -07:00
bool IsEmpty ( ) const {
2012-07-30 07:20:58 -07:00
return nullptr = = mHead ;
2007-03-22 10:30:00 -07:00
}
2011-09-28 23:19:26 -07:00
bool NotEmpty ( ) const {
2012-07-30 07:20:58 -07:00
return nullptr ! = mHead ;
2007-03-22 10:30:00 -07:00
}
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
2012-07-30 07:20:58 -07:00
// before aElement, or nullptr if aElement was the first.
2007-03-22 10:30:00 -07:00
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
2012-07-30 07:20:58 -07:00
nsFloatCacheFreeList ( ) : mTail ( nullptr ) { }
2007-03-22 10:30:00 -07:00
~ nsFloatCacheFreeList ( ) { }
# endif
// Reimplement trivial functions
2011-09-28 23:19:26 -07:00
bool IsEmpty ( ) const {
2012-07-30 07:20:58 -07:00
return nullptr = = mHead ;
2007-03-22 10:30:00 -07:00
}
nsFloatCache * Head ( ) const {
return mHead ;
}
nsFloatCache * Tail ( ) const {
return mTail ;
}
2011-09-28 23:19:26 -07:00
bool NotEmpty ( ) const {
2012-07-30 07:20:58 -07:00
return nullptr ! = mHead ;
2007-03-22 10:30:00 -07:00
}
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
2009-08-31 11:25:36 -07:00
// a new one if this one is empty; Set its mFloat to aFloat.
nsFloatCache * Alloc ( nsIFrame * aFloat ) ;
2007-03-22 10:30:00 -07:00
protected :
nsFloatCache * mTail ;
friend class nsFloatCacheList ;
} ;
//----------------------------------------------------------------------
# define LINE_MAX_BREAK_TYPE ((1 << 4) - 1)
2012-09-27 23:57:33 -07:00
# define LINE_MAX_CHILD_COUNT INT32_MAX
2007-03-22 10:30:00 -07:00
2012-03-10 18:32:27 -08:00
/**
* Function to create a line box and initialize it with a single frame .
2013-03-23 13:10:33 -07:00
* The allocation is infallible .
2012-03-10 18:32:27 -08:00
* If the frame was moved from another line then you ' re responsible
* for notifying that line using NoteFrameRemoved ( ) . Alternatively ,
* it ' s better to use the next function that does that for you in an
* optimal way .
*/
2007-03-22 10:30:00 -07:00
nsLineBox * NS_NewLineBox ( nsIPresShell * aPresShell , nsIFrame * aFrame ,
2012-03-10 18:32:27 -08:00
bool aIsBlock ) ;
/**
* Function to create a line box and initialize it with aCount frames
2013-03-23 13:10:33 -07:00
* that are currently on aFromLine . The allocation is infallible .
2012-03-10 18:32:27 -08:00
*/
nsLineBox * NS_NewLineBox ( nsIPresShell * aPresShell , nsLineBox * aFromLine ,
2012-08-22 08:56:38 -07:00
nsIFrame * aFrame , int32_t aCount ) ;
2007-03-22 10:30:00 -07: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
} ;
/**
* 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 .
*/
2012-05-03 17:14:02 -07:00
class nsLineBox MOZ_FINAL : public nsLineLink {
2007-03-22 10:30:00 -07:00
private :
2012-08-22 08:56:38 -07:00
nsLineBox ( nsIFrame * aFrame , int32_t aCount , bool aIsBlock ) ;
2007-03-22 10:30:00 -07:00
~ 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 ;
2012-03-10 18:32:27 -08:00
void operator delete ( void * aPtr , size_t sz ) MOZ_DELETE ;
2007-03-22 10:30:00 -07:00
public :
2012-03-10 18:32:27 -08:00
// Use these functions to allocate and destroy line boxes
2007-03-22 10:30:00 -07:00
friend nsLineBox * NS_NewLineBox ( nsIPresShell * aPresShell , nsIFrame * aFrame ,
2012-03-10 18:32:27 -08:00
bool aIsBlock ) ;
friend nsLineBox * NS_NewLineBox ( nsIPresShell * aPresShell , nsLineBox * aFromLine ,
2012-08-22 08:56:38 -07:00
nsIFrame * aFrame , int32_t aCount ) ;
2007-03-22 10:30:00 -07:00
void Destroy ( nsIPresShell * aPresShell ) ;
// mBlock bit
2011-09-28 23:19:26 -07:00
bool IsBlock ( ) const {
2007-03-22 10:30:00 -07:00
return mFlags . mBlock ;
}
2011-09-28 23:19:26 -07:00
bool IsInline ( ) const {
2007-03-22 10:30:00 -07:00
return 0 = = mFlags . mBlock ;
}
// mDirty bit
void MarkDirty ( ) {
mFlags . mDirty = 1 ;
}
void ClearDirty ( ) {
mFlags . mDirty = 0 ;
}
2011-09-28 23:19:26 -07:00
bool IsDirty ( ) const {
2007-03-22 10:30:00 -07:00
return mFlags . mDirty ;
}
// mPreviousMarginDirty bit
void MarkPreviousMarginDirty ( ) {
mFlags . mPreviousMarginDirty = 1 ;
}
void ClearPreviousMarginDirty ( ) {
mFlags . mPreviousMarginDirty = 0 ;
}
2011-09-28 23:19:26 -07:00
bool IsPreviousMarginDirty ( ) const {
2007-03-22 10:30:00 -07:00
return mFlags . mPreviousMarginDirty ;
}
// mHasClearance bit
void SetHasClearance ( ) {
mFlags . mHasClearance = 1 ;
}
void ClearHasClearance ( ) {
mFlags . mHasClearance = 0 ;
}
2011-09-28 23:19:26 -07:00
bool HasClearance ( ) const {
2007-03-22 10:30:00 -07:00
return mFlags . mHasClearance ;
}
// mImpactedByFloat bit
2011-09-28 23:19:26 -07:00
void SetLineIsImpactedByFloat ( bool aValue ) {
2007-03-22 10:30:00 -07:00
mFlags . mImpactedByFloat = aValue ;
}
2011-09-28 23:19:26 -07:00
bool IsImpactedByFloat ( ) const {
2007-03-22 10:30:00 -07:00
return mFlags . mImpactedByFloat ;
}
// mLineWrapped bit
2011-09-28 23:19:26 -07:00
void SetLineWrapped ( bool aOn ) {
2007-03-22 10:30:00 -07:00
mFlags . mLineWrapped = aOn ;
}
2011-09-28 23:19:26 -07:00
bool IsLineWrapped ( ) const {
2007-03-22 10:30:00 -07:00
return mFlags . mLineWrapped ;
}
2007-09-17 20:00:16 -07:00
// mInvalidateTextRuns bit
2011-09-28 23:19:26 -07:00
void SetInvalidateTextRuns ( bool aOn ) {
2007-09-17 20:00:16 -07:00
mFlags . mInvalidateTextRuns = aOn ;
}
2011-09-28 23:19:26 -07:00
bool GetInvalidateTextRuns ( ) const {
2007-09-17 20:00:16 -07:00
return mFlags . mInvalidateTextRuns ;
}
2007-03-22 10:30:00 -07:00
// mResizeReflowOptimizationDisabled bit
void DisableResizeReflowOptimization ( ) {
2011-10-17 07:59:28 -07:00
mFlags . mResizeReflowOptimizationDisabled = true ;
2007-03-22 10:30:00 -07:00
}
void EnableResizeReflowOptimization ( ) {
2011-10-17 07:59:28 -07:00
mFlags . mResizeReflowOptimizationDisabled = false ;
2007-03-22 10:30:00 -07:00
}
2011-09-28 23:19:26 -07:00
bool ResizeReflowOptimizationDisabled ( ) const {
2007-03-22 10:30:00 -07:00
return mFlags . mResizeReflowOptimizationDisabled ;
}
2009-08-10 19:48:42 -07:00
// mHasBullet bit
void SetHasBullet ( ) {
2011-10-17 07:59:28 -07:00
mFlags . mHasBullet = true ;
2009-08-10 19:48:42 -07:00
InvalidateCachedIsEmpty ( ) ;
}
void ClearHasBullet ( ) {
2011-10-17 07:59:28 -07:00
mFlags . mHasBullet = false ;
2009-08-10 19:48:42 -07:00
InvalidateCachedIsEmpty ( ) ;
}
2011-09-28 23:19:26 -07:00
bool HasBullet ( ) const {
2009-08-10 19:48:42 -07:00
return mFlags . mHasBullet ;
}
2010-08-05 21:59:20 -07:00
// mHadFloatPushed bit
void SetHadFloatPushed ( ) {
2011-10-17 07:59:28 -07:00
mFlags . mHadFloatPushed = true ;
2010-08-05 21:59:20 -07:00
}
void ClearHadFloatPushed ( ) {
2011-10-17 07:59:28 -07:00
mFlags . mHadFloatPushed = false ;
2010-08-05 21:59:20 -07:00
}
2011-09-28 23:19:26 -07:00
bool HadFloatPushed ( ) const {
2010-08-05 21:59:20 -07:00
return mFlags . mHadFloatPushed ;
}
2012-03-10 18:32:27 -08:00
private :
// Add a hash table for fast lookup when the line has more frames than this.
2012-08-22 08:56:38 -07:00
static const uint32_t kMinChildCountForHashtable = 200 ;
2012-03-10 18:32:27 -08:00
/**
* Take ownership of aFromLine ' s hash table and remove the frames that
* stay on aFromLine from it , i . e . aFromLineNewCount frames starting with
* mFirstChild . This method is used to optimize moving a large number
* of frames from one line to the next .
*/
2012-08-22 08:56:38 -07:00
void StealHashTableFrom ( nsLineBox * aFromLine , uint32_t aFromLineNewCount ) ;
2010-08-05 21:59:20 -07:00
2012-03-10 18:32:27 -08:00
/**
* Does the equivalent of this - > NoteFrameAdded and aFromLine - > NoteFrameRemoved
* for each frame on this line , but in a optimized way .
*/
void NoteFramesMovedFrom ( nsLineBox * aFromLine ) ;
void SwitchToHashtable ( )
{
MOZ_ASSERT ( ! mFlags . mHasHashedFrames ) ;
2012-08-22 08:56:38 -07:00
uint32_t count = GetChildCount ( ) ;
2012-03-10 18:32:27 -08:00
mFlags . mHasHashedFrames = 1 ;
2012-08-22 08:56:38 -07:00
uint32_t minSize =
2013-01-15 04:22:03 -08:00
std : : max ( kMinChildCountForHashtable , uint32_t ( PL_DHASH_MIN_SIZE ) ) ;
2013-09-02 01:41:57 -07:00
mFrames = new nsTHashtable < nsPtrHashKey < nsIFrame > > ( std : : max ( count , minSize ) ) ;
2012-03-10 18:32:27 -08:00
for ( nsIFrame * f = mFirstChild ; count - - > 0 ; f = f - > GetNextSibling ( ) ) {
mFrames - > PutEntry ( f ) ;
}
}
void SwitchToCounter ( ) {
MOZ_ASSERT ( mFlags . mHasHashedFrames ) ;
2012-08-22 08:56:38 -07:00
uint32_t count = GetChildCount ( ) ;
2012-03-10 18:32:27 -08:00
delete mFrames ;
mFlags . mHasHashedFrames = 0 ;
mChildCount = count ;
}
public :
2012-08-22 08:56:38 -07:00
int32_t GetChildCount ( ) const {
2012-10-26 06:32:10 -07:00
return MOZ_UNLIKELY ( mFlags . mHasHashedFrames ) ? mFrames - > Count ( ) : mChildCount ;
2007-03-22 10:30:00 -07:00
}
2012-03-10 18:32:27 -08:00
/**
* Register that aFrame is now on this line .
*/
void NoteFrameAdded ( nsIFrame * aFrame ) {
2012-10-26 06:32:10 -07:00
if ( MOZ_UNLIKELY ( mFlags . mHasHashedFrames ) ) {
2012-03-10 18:32:27 -08:00
mFrames - > PutEntry ( aFrame ) ;
} else {
if ( + + mChildCount > = kMinChildCountForHashtable ) {
SwitchToHashtable ( ) ;
}
2007-03-22 10:30:00 -07:00
}
2012-03-10 18:32:27 -08:00
}
/**
* Register that aFrame is not on this line anymore .
*/
void NoteFrameRemoved ( nsIFrame * aFrame ) {
MOZ_ASSERT ( GetChildCount ( ) > 0 ) ;
2012-10-26 06:32:10 -07:00
if ( MOZ_UNLIKELY ( mFlags . mHasHashedFrames ) ) {
2012-03-10 18:32:27 -08:00
mFrames - > RemoveEntry ( aFrame ) ;
if ( mFrames - > Count ( ) < kMinChildCountForHashtable ) {
SwitchToCounter ( ) ;
}
} else {
- - mChildCount ;
2007-03-22 10:30:00 -07:00
}
}
// 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.
2011-09-28 23:19:26 -07:00
bool HasBreakBefore ( ) const {
2007-03-22 10:30:00 -07:00
return IsBlock ( ) & & NS_STYLE_CLEAR_NONE ! = mFlags . mBreakType ;
}
2012-08-22 08:56:38 -07:00
void SetBreakTypeBefore ( uint8_t aBreakType ) {
2007-03-22 10:30:00 -07:00
NS_ASSERTION ( IsBlock ( ) , " Only blocks have break-before " ) ;
2014-03-02 09:42:16 -08:00
NS_ASSERTION ( aBreakType = = NS_STYLE_CLEAR_NONE | |
aBreakType = = NS_STYLE_CLEAR_LEFT | |
aBreakType = = NS_STYLE_CLEAR_RIGHT | |
aBreakType = = NS_STYLE_CLEAR_BOTH ,
2007-03-22 10:30:00 -07:00
" Only float break types are allowed before a line " ) ;
mFlags . mBreakType = aBreakType ;
}
2012-08-22 08:56:38 -07:00
uint8_t GetBreakTypeBefore ( ) const {
2007-03-22 10:30:00 -07:00
return IsBlock ( ) ? mFlags . mBreakType : NS_STYLE_CLEAR_NONE ;
}
2011-09-28 23:19:26 -07:00
bool HasBreakAfter ( ) const {
2007-03-22 10:30:00 -07:00
return ! IsBlock ( ) & & NS_STYLE_CLEAR_NONE ! = mFlags . mBreakType ;
}
2012-08-22 08:56:38 -07:00
void SetBreakTypeAfter ( uint8_t aBreakType ) {
2007-03-22 10:30:00 -07:00
NS_ASSERTION ( ! IsBlock ( ) , " Only inlines have break-after " ) ;
NS_ASSERTION ( aBreakType < = LINE_MAX_BREAK_TYPE , " bad break type " ) ;
mFlags . mBreakType = aBreakType ;
}
2011-09-28 23:19:26 -07:00
bool HasFloatBreakAfter ( ) const {
2007-03-22 10:30:00 -07:00
return ! IsBlock ( ) & & ( NS_STYLE_CLEAR_LEFT = = mFlags . mBreakType | |
NS_STYLE_CLEAR_RIGHT = = mFlags . mBreakType | |
2014-03-02 09:42:16 -08:00
NS_STYLE_CLEAR_BOTH = = mFlags . mBreakType ) ;
2007-03-22 10:30:00 -07:00
}
2012-08-22 08:56:38 -07:00
uint8_t GetBreakTypeAfter ( ) const {
2007-03-22 10:30:00 -07:00
return ! IsBlock ( ) ? mFlags . mBreakType : NS_STYLE_CLEAR_NONE ;
}
2014-06-20 02:55:35 -07:00
// mCarriedOutBEndMargin value
nsCollapsingMargin GetCarriedOutBEndMargin ( ) const ;
2011-10-17 07:59:28 -07:00
// Returns true if the margin changed
2014-06-20 02:55:35 -07:00
bool SetCarriedOutBEndMargin ( nsCollapsingMargin aValue ) ;
2007-03-22 10:30:00 -07:00
// mFloats
2011-09-28 23:19:26 -07:00
bool HasFloats ( ) const {
2007-03-22 10:30:00 -07:00
return ( IsInline ( ) & & mInlineData ) & & mInlineData - > mFloats . NotEmpty ( ) ;
}
nsFloatCache * GetFirstFloat ( ) ;
void FreeFloats ( nsFloatCacheFreeList & aFreeList ) ;
void AppendFloats ( nsFloatCacheFreeList & aFreeList ) ;
2011-09-28 23:19:26 -07:00
bool RemoveFloat ( nsIFrame * aFrame ) ;
2007-03-22 10:30:00 -07: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').
2010-10-06 21:25:45 -07:00
void SetOverflowAreas ( const nsOverflowAreas & aOverflowAreas ) ;
nsRect GetOverflowArea ( nsOverflowType aType ) {
2014-04-16 01:03:28 -07:00
return mData ? mData - > mOverflowAreas . Overflow ( aType ) : GetPhysicalBounds ( ) ;
2007-03-22 10:30:00 -07:00
}
2010-10-06 21:25:45 -07:00
nsOverflowAreas GetOverflowAreas ( ) {
if ( mData ) {
return mData - > mOverflowAreas ;
}
2014-04-16 01:03:28 -07:00
nsRect bounds = GetPhysicalBounds ( ) ;
return nsOverflowAreas ( bounds , bounds ) ;
2010-10-06 21:25:45 -07:00
}
nsRect GetVisualOverflowArea ( )
{ return GetOverflowArea ( eVisualOverflow ) ; }
nsRect GetScrollableOverflowArea ( )
{ return GetOverflowArea ( eScrollableOverflow ) ; }
2007-03-22 10:30:00 -07:00
2014-04-16 01:03:28 -07:00
void SlideBy ( nscoord aDBCoord , nscoord aContainerWidth ) {
NS_ASSERTION ( aContainerWidth = = mContainerWidth | | mContainerWidth = = - 1 ,
" container width doesn't match " ) ;
mContainerWidth = aContainerWidth ;
mBounds . BStart ( mWritingMode ) + = aDBCoord ;
2007-03-22 10:30:00 -07:00
if ( mData ) {
2010-10-06 21:25:45 -07:00
NS_FOR_FRAME_OVERFLOW_TYPES ( otype ) {
2014-04-16 01:03:28 -07:00
mData - > mOverflowAreas . Overflow ( otype ) . y + = aDBCoord ;
2010-10-06 21:25:45 -07:00
}
2007-03-22 10:30:00 -07:00
}
}
2014-04-16 01:03:28 -07:00
void IndentBy ( nscoord aDICoord , nscoord aContainerWidth ) {
NS_ASSERTION ( aContainerWidth = = mContainerWidth | | mContainerWidth = = - 1 ,
" container width doesn't match " ) ;
mContainerWidth = aContainerWidth ;
mBounds . IStart ( mWritingMode ) + = aDICoord ;
}
void ExpandBy ( nscoord aDISize , nscoord aContainerWidth ) {
NS_ASSERTION ( aContainerWidth = = mContainerWidth | | mContainerWidth = = - 1 ,
" container width doesn't match " ) ;
mContainerWidth = aContainerWidth ;
mBounds . ISize ( mWritingMode ) + = aDISize ;
}
2007-03-22 10:30:00 -07:00
/**
2014-06-17 05:19:38 -07:00
* The logical ascent ( distance from block - start to baseline ) of the
* linebox is the logical 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 .
2007-03-22 10:30:00 -07:00
*
* This is currently unused for block lines .
*/
2014-06-17 05:19:38 -07:00
nscoord GetLogicalAscent ( ) const { return mAscent ; }
void SetLogicalAscent ( nscoord aAscent ) { mAscent = aAscent ; }
2007-03-22 10:30:00 -07:00
2014-04-16 01:03:28 -07:00
nscoord BStart ( ) const {
return mBounds . BStart ( mWritingMode ) ;
}
nscoord BSize ( ) const {
return mBounds . BSize ( mWritingMode ) ;
}
nscoord BEnd ( ) const {
return mBounds . BEnd ( mWritingMode ) ;
}
nscoord IStart ( ) const {
return mBounds . IStart ( mWritingMode ) ;
}
nscoord ISize ( ) const {
return mBounds . ISize ( mWritingMode ) ;
}
nscoord IEnd ( ) const {
return mBounds . IEnd ( mWritingMode ) ;
}
void SetBoundsEmpty ( ) {
mBounds . IStart ( mWritingMode ) = 0 ;
mBounds . ISize ( mWritingMode ) = 0 ;
mBounds . BStart ( mWritingMode ) = 0 ;
mBounds . BSize ( mWritingMode ) = 0 ;
2007-03-22 10:30:00 -07:00
}
2009-12-23 21:21:15 -08:00
static void DeleteLineList ( nsPresContext * aPresContext , nsLineList & aLines ,
2012-10-14 18:34:23 -07:00
nsIFrame * aDestructRoot , nsFrameList * aFrames ) ;
2007-03-22 10:30:00 -07:00
// search from end to beginning of [aBegin, aEnd)
2011-10-17 07:59:28 -07:00
// Returns true if it found the line and false if not.
2007-03-22 10:30:00 -07:00
// Moves aEnd as it searches so that aEnd points to the resulting line.
2009-10-02 09:31:43 -07:00
// aLastFrameBeforeEnd is the last frame before aEnd (so if aEnd is
// the end of the line list, it's just the last frame in the frame
// list).
2011-09-28 23:19:26 -07:00
static bool RFindLineContaining ( nsIFrame * aFrame ,
2007-03-22 10:30:00 -07:00
const nsLineList_iterator & aBegin ,
nsLineList_iterator & aEnd ,
2009-10-02 09:31:43 -07:00
nsIFrame * aLastFrameBeforeEnd ,
2012-08-22 08:56:38 -07:00
int32_t * aFrameIndexInLine ) ;
2007-03-22 10:30:00 -07:00
2014-01-05 15:31:14 -08:00
# ifdef DEBUG_FRAME_DUMP
2012-08-22 08:56:38 -07:00
char * StateToString ( char * aBuf , int32_t aBufSize ) const ;
2007-03-22 10:30:00 -07:00
2012-09-19 07:36:35 -07:00
void List ( FILE * out , int32_t aIndent , uint32_t aFlags = 0 ) const ;
2014-01-26 14:07:02 -08:00
void List ( FILE * out = stderr , const char * aPrefix = " " , uint32_t aFlags = 0 ) const ;
2007-03-22 10:30:00 -07:00
nsIFrame * LastChild ( ) const ;
2012-03-07 17:57:37 -08:00
# endif
2007-03-22 10:30:00 -07:00
2012-03-10 18:32:27 -08:00
private :
2012-08-22 08:56:38 -07:00
int32_t IndexOf ( nsIFrame * aFrame ) const ;
2012-03-10 18:32:27 -08:00
public :
2007-03-22 10:30:00 -07:00
2011-09-28 23:19:26 -07:00
bool Contains ( nsIFrame * aFrame ) const {
2012-10-26 06:32:10 -07:00
return MOZ_UNLIKELY ( mFlags . mHasHashedFrames ) ? mFrames - > Contains ( aFrame )
2012-03-10 18:32:27 -08:00
: IndexOf ( aFrame ) > = 0 ;
2007-03-22 10:30:00 -07:00
}
// whether the line box is "logically" empty (just like nsIFrame::IsEmpty)
2011-09-28 23:19:26 -07:00
bool IsEmpty ( ) const ;
2007-03-22 10:30:00 -07: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 block.
2011-11-06 21:25:56 -08:00
bool CachedIsEmpty ( ) ;
2007-03-22 10:30:00 -07:00
void InvalidateCachedIsEmpty ( ) {
2011-10-17 07:59:28 -07:00
mFlags . mEmptyCacheValid = false ;
2007-03-22 10:30:00 -07:00
}
// For debugging purposes
2011-11-06 21:25:56 -08:00
bool IsValidCachedIsEmpty ( ) {
2007-03-22 10:30:00 -07:00
return mFlags . mEmptyCacheValid ;
}
# ifdef DEBUG
2012-08-22 08:56:38 -07:00
static int32_t GetCtorCount ( ) ;
2007-03-22 10:30:00 -07:00
# endif
nsIFrame * mFirstChild ;
2014-04-16 01:03:28 -07:00
mozilla : : WritingMode mWritingMode ;
nscoord mContainerWidth ;
private :
mozilla : : LogicalRect mBounds ;
public :
const mozilla : : LogicalRect & GetBounds ( ) { return mBounds ; }
nsRect GetPhysicalBounds ( ) const
{
if ( mBounds . IsEmpty ( ) ) {
return nsRect ( 0 , 0 , 0 , 0 ) ;
}
NS_ASSERTION ( mContainerWidth ! = - 1 , " mContainerWidth not initialized " ) ;
return mBounds . GetPhysicalRect ( mWritingMode , mContainerWidth ) ;
}
void SetBounds ( mozilla : : WritingMode aWritingMode ,
nscoord aIStart , nscoord aBStart ,
nscoord aISize , nscoord aBSize ,
nscoord aContainerWidth )
{
mWritingMode = aWritingMode ;
mContainerWidth = aContainerWidth ;
mBounds = mozilla : : LogicalRect ( aWritingMode , aIStart , aBStart ,
aISize , aBSize ) ;
}
void SetBounds ( mozilla : : WritingMode aWritingMode ,
nsRect aRect , nscoord aContainerWidth )
{
mWritingMode = aWritingMode ;
mContainerWidth = aContainerWidth ;
mBounds = mozilla : : LogicalRect ( aWritingMode , aRect , aContainerWidth ) ;
}
2007-03-22 10:30:00 -07:00
2012-03-10 18:32:27 -08:00
// mFlags.mHasHashedFrames says which one to use
union {
nsTHashtable < nsPtrHashKey < nsIFrame > > * mFrames ;
2012-08-22 08:56:38 -07:00
uint32_t mChildCount ;
2012-03-10 18:32:27 -08:00
} ;
2007-03-22 10:30:00 -07:00
struct FlagBits {
2012-08-22 08:56:38 -07:00
uint32_t mDirty : 1 ;
uint32_t mPreviousMarginDirty : 1 ;
uint32_t mHasClearance : 1 ;
uint32_t mBlock : 1 ;
uint32_t mImpactedByFloat : 1 ;
uint32_t mLineWrapped : 1 ;
uint32_t mInvalidateTextRuns : 1 ;
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
uint32_t mEmptyCacheValid : 1 ;
uint32_t mEmptyCacheState : 1 ;
2009-08-10 19:48:42 -07:00
// mHasBullet indicates that this is an inline line whose block's
2009-09-11 03:46:36 -07:00
// bullet is adjacent to this line and non-empty.
2012-08-22 08:56:38 -07:00
uint32_t mHasBullet : 1 ;
2010-08-05 21:59:20 -07:00
// Indicates that this line *may* have a placeholder for a float
// that was pushed to a later column or page.
2012-08-22 08:56:38 -07:00
uint32_t mHadFloatPushed : 1 ;
uint32_t mHasHashedFrames : 1 ;
uint32_t mBreakType : 4 ;
2007-03-22 10:30:00 -07:00
} ;
struct ExtraData {
2010-10-06 21:25:45 -07:00
ExtraData ( const nsRect & aBounds ) : mOverflowAreas ( aBounds , aBounds ) {
2007-03-22 10:30:00 -07:00
}
2010-10-06 21:25:45 -07:00
nsOverflowAreas mOverflowAreas ;
2007-03-22 10:30:00 -07:00
} ;
struct ExtraBlockData : public ExtraData {
ExtraBlockData ( const nsRect & aBounds )
: ExtraData ( aBounds ) ,
2014-06-20 02:55:35 -07:00
mCarriedOutBEndMargin ( )
2007-03-22 10:30:00 -07:00
{
}
2014-06-20 02:55:35 -07:00
nsCollapsingMargin mCarriedOutBEndMargin ;
2007-03-22 10:30:00 -07:00
} ;
struct ExtraInlineData : public ExtraData {
ExtraInlineData ( const nsRect & aBounds ) : ExtraData ( aBounds ) {
}
nsFloatCacheList mFloats ;
} ;
protected :
nscoord mAscent ; // see |SetAscent| / |GetAscent|
union {
2012-08-22 08:56:38 -07:00
uint32_t mAllFlags ;
2007-03-22 10:30:00 -07:00
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 ;
2012-08-22 08:56:38 -07:00
typedef uint32_t size_type ;
typedef int32_t difference_type ;
2007-03-22 10:30:00 -07:00
typedef nsLineLink link_type ;
2012-06-25 12:59:42 -07:00
# ifdef DEBUG
2007-03-22 10:30:00 -07:00
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.
2011-09-28 23:19:26 -07:00
bool operator = = ( const iterator_self_type aOther ) const
2007-07-10 17:55:15 -07:00
{
2009-02-10 01:23:05 -08:00
NS_ABORT_IF_FALSE ( mListLink = = aOther . mListLink , " comparing iterators over different lists " ) ;
2007-07-10 17:55:15 -07:00
return mCurrent = = aOther . mCurrent ;
}
2011-09-28 23:19:26 -07:00
bool operator ! = ( const iterator_self_type aOther ) const
2007-07-10 17:55:15 -07:00
{
2009-02-10 01:23:05 -08:00
NS_ABORT_IF_FALSE ( mListLink = = aOther . mListLink , " comparing iterators over different lists " ) ;
2007-07-10 17:55:15 -07:00
return mCurrent ! = aOther . mCurrent ;
}
2011-09-28 23:19:26 -07:00
bool operator = = ( const iterator_self_type aOther )
2007-07-10 17:55:15 -07:00
{
2009-02-10 01:23:05 -08:00
NS_ABORT_IF_FALSE ( mListLink = = aOther . mListLink , " comparing iterators over different lists " ) ;
2007-07-10 17:55:15 -07:00
return mCurrent = = aOther . mCurrent ;
}
2011-09-28 23:19:26 -07:00
bool operator ! = ( const iterator_self_type aOther )
2007-07-10 17:55:15 -07:00
{
2009-02-10 01:23:05 -08:00
NS_ABORT_IF_FALSE ( mListLink = = aOther . mListLink , " comparing iterators over different lists " ) ;
2007-07-10 17:55:15 -07:00
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 ;
2012-08-22 08:56:38 -07:00
typedef uint32_t size_type ;
typedef int32_t difference_type ;
2007-03-22 10:30:00 -07:00
typedef nsLineLink link_type ;
2012-06-25 12:59:42 -07:00
# ifdef DEBUG
2007-03-22 10:30:00 -07:00
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.
2011-09-28 23:19:26 -07:00
bool 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 ;
}
2011-09-28 23:19:26 -07:00
bool 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 ;
}
2011-09-28 23:19:26 -07:00
bool 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 ;
}
2011-09-28 23:19:26 -07:00
bool 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 ;
2012-08-22 08:56:38 -07:00
typedef uint32_t size_type ;
typedef int32_t difference_type ;
2007-03-22 10:30:00 -07:00
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.
2011-09-28 23:19:26 -07:00
bool 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 ;
}
2011-09-28 23:19:26 -07:00
bool 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 ;
}
2011-09-28 23:19:26 -07:00
bool 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 ;
}
2011-09-28 23:19:26 -07:00
bool 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 ;
2012-08-22 08:56:38 -07:00
typedef uint32_t size_type ;
typedef int32_t difference_type ;
2007-03-22 10:30:00 -07:00
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.
2011-09-28 23:19:26 -07:00
bool 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 ;
}
2011-09-28 23:19:26 -07:00
bool 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 ;
}
2011-09-28 23:19:26 -07:00
bool 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 ;
}
2011-09-28 23:19:26 -07:00
bool 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 ;
2012-08-22 08:56:38 -07:00
typedef uint32_t size_type ;
typedef int32_t difference_type ;
2007-03-22 10:30:00 -07:00
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 ( )
{
2009-09-29 18:34:46 -07:00
MOZ_COUNT_CTOR ( nsLineList ) ;
2007-03-22 10:30:00 -07:00
clear ( ) ;
}
2009-09-29 18:34:46 -07:00
~ nsLineList ( )
{
MOZ_COUNT_DTOR ( nsLineList ) ;
}
2007-03-22 10:30:00 -07:00
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 ;
}
2010-09-08 17:15:24 -07:00
reverse_iterator rbegin ( nsLineBox * aLine )
{
reverse_iterator rv ;
rv . mCurrent = aLine ;
# ifdef DEBUG
rv . mListLink = & mLink ;
# endif
return rv ;
}
2007-03-22 10:30:00 -07:00
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 ;
}
2011-09-28 23:19:26 -07:00
bool empty ( ) const
2007-03-22 10:30:00 -07:00
{
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 ;
2012-07-30 07:20:58 -07:00
// mLink._mNext->_mNext = nullptr;
// mLink._mNext->_mPrev = nullptr;
2007-03-22 10:30:00 -07:00
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 ;
2012-07-30 07:20:58 -07:00
// mLink._mPrev->_mPrev = nullptr;
// mLink._mPrev->_mNext = nullptr;
2007-03-22 10:30:00 -07:00
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 ;
2011-04-22 18:36:23 -07:00
if ( ! empty ( ) ) {
mLink . _mNext - > _mPrev = & mLink ;
mLink . _mPrev - > _mNext = & mLink ;
}
if ( ! y . empty ( ) ) {
y . mLink . _mNext - > _mPrev = & y . mLink ;
y . mLink . _mPrev - > _mNext = & y . mLink ;
}
2007-03-22 10:30:00 -07:00
}
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 )
}
//----------------------------------------------------------------------
2011-11-20 22:21:16 -08:00
class nsLineIterator MOZ_FINAL : public nsILineIterator
2008-10-30 12:17:59 -07:00
{
2007-03-22 10:30:00 -07:00
public :
nsLineIterator ( ) ;
2008-10-30 12:17:59 -07:00
~ nsLineIterator ( ) ;
2007-03-22 10:30:00 -07:00
2013-05-14 09:33:23 -07:00
virtual void DisposeLineIterator ( ) MOZ_OVERRIDE ;
2007-03-22 10:30:00 -07:00
2013-05-14 09:33:23 -07:00
virtual int32_t GetNumLines ( ) MOZ_OVERRIDE ;
virtual bool GetDirection ( ) MOZ_OVERRIDE ;
2012-08-22 08:56:38 -07:00
NS_IMETHOD GetLine ( int32_t aLineNumber ,
2007-03-22 10:30:00 -07:00
nsIFrame * * aFirstFrameOnLine ,
2012-08-22 08:56:38 -07:00
int32_t * aNumFramesOnLine ,
2007-03-22 10:30:00 -07:00
nsRect & aLineBounds ,
2013-05-14 09:33:23 -07:00
uint32_t * aLineFlags ) MOZ_OVERRIDE ;
virtual int32_t FindLineContaining ( nsIFrame * aFrame , int32_t aStartLine = 0 ) MOZ_OVERRIDE ;
2012-08-22 08:56:38 -07:00
NS_IMETHOD FindFrameAt ( int32_t aLineNumber ,
2007-03-22 10:30:00 -07:00
nscoord aX ,
nsIFrame * * aFrameFound ,
2011-09-28 23:19:26 -07:00
bool * aXIsBeforeFirstFrame ,
2013-05-14 09:33:23 -07:00
bool * aXIsAfterLastFrame ) MOZ_OVERRIDE ;
2007-03-22 10:30:00 -07:00
2013-05-14 09:33:23 -07:00
NS_IMETHOD GetNextSiblingOnLine ( nsIFrame * & aFrame , int32_t aLineNumber ) MOZ_OVERRIDE ;
2012-08-22 08:56:38 -07:00
NS_IMETHOD CheckLineOrder ( int32_t aLine ,
2011-09-28 23:19:26 -07:00
bool * aIsReordered ,
2007-03-22 10:30:00 -07:00
nsIFrame * * aFirstVisual ,
2013-05-14 09:33:23 -07:00
nsIFrame * * aLastVisual ) MOZ_OVERRIDE ;
2011-09-28 23:19:26 -07:00
nsresult Init ( nsLineList & aLines , bool aRightToLeft ) ;
2007-03-22 10:30:00 -07:00
2008-10-30 12:17:59 -07:00
private :
2007-03-22 10:30:00 -07:00
nsLineBox * PrevLine ( ) {
if ( 0 = = mIndex ) {
2012-07-30 07:20:58 -07:00
return nullptr ;
2007-03-22 10:30:00 -07:00
}
return mLines [ - - mIndex ] ;
}
nsLineBox * NextLine ( ) {
if ( mIndex > = mNumLines - 1 ) {
2012-07-30 07:20:58 -07:00
return nullptr ;
2007-03-22 10:30:00 -07:00
}
return mLines [ + + mIndex ] ;
}
2012-08-22 08:56:38 -07:00
nsLineBox * LineAt ( int32_t aIndex ) {
2007-03-22 10:30:00 -07:00
if ( ( aIndex < 0 ) | | ( aIndex > = mNumLines ) ) {
2012-07-30 07:20:58 -07:00
return nullptr ;
2007-03-22 10:30:00 -07:00
}
return mLines [ aIndex ] ;
}
nsLineBox * * mLines ;
2012-08-22 08:56:38 -07:00
int32_t mIndex ;
int32_t mNumLines ;
2011-09-28 23:19:26 -07:00
bool mRightToLeft ;
2007-03-22 10:30:00 -07:00
} ;
# endif /* nsLineBox_h___ */