layout/generic/nsLineBox.h

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/layout/generic/nsLineBox.h	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,1736 @@
     1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     1.5 +// vim:cindent:ts=2:et:sw=2:
     1.6 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.9 +
    1.10 +/* representation of one line within a block frame, a CSS line box */
    1.11 +
    1.12 +#ifndef nsLineBox_h___
    1.13 +#define nsLineBox_h___
    1.14 +
    1.15 +#include "mozilla/Attributes.h"
    1.16 +#include "mozilla/Likely.h"
    1.17 +
    1.18 +#include "nsILineIterator.h"
    1.19 +#include "nsIFrame.h"
    1.20 +#include <algorithm>
    1.21 +
    1.22 +class nsLineBox;
    1.23 +class nsFloatCache;
    1.24 +class nsFloatCacheList;
    1.25 +class nsFloatCacheFreeList;
    1.26 +
    1.27 +// State cached after reflowing a float. This state is used during
    1.28 +// incremental reflow when we avoid reflowing a float.
    1.29 +class nsFloatCache {
    1.30 +public:
    1.31 +  nsFloatCache();
    1.32 +#ifdef NS_BUILD_REFCNT_LOGGING
    1.33 +  ~nsFloatCache();
    1.34 +#else
    1.35 +  ~nsFloatCache() { }
    1.36 +#endif
    1.37 +
    1.38 +  nsFloatCache* Next() const { return mNext; }
    1.39 +
    1.40 +  nsIFrame* mFloat;                     // floating frame
    1.41 +
    1.42 +protected:
    1.43 +  nsFloatCache* mNext;
    1.44 +
    1.45 +  friend class nsFloatCacheList;
    1.46 +  friend class nsFloatCacheFreeList;
    1.47 +};
    1.48 +
    1.49 +//----------------------------------------
    1.50 +
    1.51 +class nsFloatCacheList {
    1.52 +public:
    1.53 +#ifdef NS_BUILD_REFCNT_LOGGING
    1.54 +  nsFloatCacheList();
    1.55 +#else
    1.56 +  nsFloatCacheList() : mHead(nullptr) { }
    1.57 +#endif
    1.58 +  ~nsFloatCacheList();
    1.59 +
    1.60 +  bool IsEmpty() const {
    1.61 +    return nullptr == mHead;
    1.62 +  }
    1.63 +
    1.64 +  bool NotEmpty() const {
    1.65 +    return nullptr != mHead;
    1.66 +  }
    1.67 +
    1.68 +  nsFloatCache* Head() const {
    1.69 +    return mHead;
    1.70 +  }
    1.71 +
    1.72 +  nsFloatCache* Tail() const;
    1.73 +
    1.74 +  void DeleteAll();
    1.75 +
    1.76 +  nsFloatCache* Find(nsIFrame* aOutOfFlowFrame);
    1.77 +
    1.78 +  // Remove a nsFloatCache from this list.  Deleting this nsFloatCache
    1.79 +  // becomes the caller's responsibility.
    1.80 +  void Remove(nsFloatCache* aElement) { RemoveAndReturnPrev(aElement); }
    1.81 +  
    1.82 +  // Steal away aList's nsFloatCache objects and put them in this
    1.83 +  // list.  aList must not be empty.
    1.84 +  void Append(nsFloatCacheFreeList& aList);
    1.85 +
    1.86 +protected:
    1.87 +  nsFloatCache* mHead;
    1.88 +
    1.89 +  // Remove a nsFloatCache from this list.  Deleting this nsFloatCache
    1.90 +  // becomes the caller's responsibility. Returns the nsFloatCache that was
    1.91 +  // before aElement, or nullptr if aElement was the first.
    1.92 +  nsFloatCache* RemoveAndReturnPrev(nsFloatCache* aElement);
    1.93 +  
    1.94 +  friend class nsFloatCacheFreeList;
    1.95 +};
    1.96 +
    1.97 +//---------------------------------------
    1.98 +// Like nsFloatCacheList, but with fast access to the tail
    1.99 +
   1.100 +class nsFloatCacheFreeList : private nsFloatCacheList {
   1.101 +public:
   1.102 +#ifdef NS_BUILD_REFCNT_LOGGING
   1.103 +  nsFloatCacheFreeList();
   1.104 +  ~nsFloatCacheFreeList();
   1.105 +#else
   1.106 +  nsFloatCacheFreeList() : mTail(nullptr) { }
   1.107 +  ~nsFloatCacheFreeList() { }
   1.108 +#endif
   1.109 +
   1.110 +  // Reimplement trivial functions
   1.111 +  bool IsEmpty() const {
   1.112 +    return nullptr == mHead;
   1.113 +  }
   1.114 +
   1.115 +  nsFloatCache* Head() const {
   1.116 +    return mHead;
   1.117 +  }
   1.118 +
   1.119 +  nsFloatCache* Tail() const {
   1.120 +    return mTail;
   1.121 +  }
   1.122 +  
   1.123 +  bool NotEmpty() const {
   1.124 +    return nullptr != mHead;
   1.125 +  }
   1.126 +
   1.127 +  void DeleteAll();
   1.128 +
   1.129 +  // Steal away aList's nsFloatCache objects and put them on this
   1.130 +  // free-list.  aList must not be empty.
   1.131 +  void Append(nsFloatCacheList& aList);
   1.132 +
   1.133 +  void Append(nsFloatCache* aFloatCache);
   1.134 +
   1.135 +  void Remove(nsFloatCache* aElement);
   1.136 +
   1.137 +  // Remove an nsFloatCache object from this list and return it, or create
   1.138 +  // a new one if this one is empty; Set its mFloat to aFloat.
   1.139 +  nsFloatCache* Alloc(nsIFrame* aFloat);
   1.140 +  
   1.141 +protected:
   1.142 +  nsFloatCache* mTail;
   1.143 +
   1.144 +  friend class nsFloatCacheList;
   1.145 +};
   1.146 +
   1.147 +//----------------------------------------------------------------------
   1.148 +
   1.149 +#define LINE_MAX_BREAK_TYPE  ((1 << 4) - 1)
   1.150 +#define LINE_MAX_CHILD_COUNT INT32_MAX
   1.151 +
   1.152 +/**
   1.153 + * Function to create a line box and initialize it with a single frame.
   1.154 + * The allocation is infallible.
   1.155 + * If the frame was moved from another line then you're responsible
   1.156 + * for notifying that line using NoteFrameRemoved().  Alternatively,
   1.157 + * it's better to use the next function that does that for you in an
   1.158 + * optimal way.
   1.159 + */
   1.160 +nsLineBox* NS_NewLineBox(nsIPresShell* aPresShell, nsIFrame* aFrame,
   1.161 +                         bool aIsBlock);
   1.162 +/**
   1.163 + * Function to create a line box and initialize it with aCount frames
   1.164 + * that are currently on aFromLine.  The allocation is infallible.
   1.165 + */
   1.166 +nsLineBox* NS_NewLineBox(nsIPresShell* aPresShell, nsLineBox* aFromLine,
   1.167 +                         nsIFrame* aFrame, int32_t aCount);
   1.168 +
   1.169 +class nsLineList;
   1.170 +
   1.171 +// don't use the following names outside of this file.  Instead, use
   1.172 +// nsLineList::iterator, etc.  These are just here to allow them to
   1.173 +// be specified as parameters to methods of nsLineBox.
   1.174 +class nsLineList_iterator;
   1.175 +class nsLineList_const_iterator;
   1.176 +class nsLineList_reverse_iterator;
   1.177 +class nsLineList_const_reverse_iterator;
   1.178 +
   1.179 +/**
   1.180 + * Users must have the class that is to be part of the list inherit
   1.181 + * from nsLineLink.  If they want to be efficient, it should be the
   1.182 + * first base class.  (This was originally nsCLink in a templatized
   1.183 + * nsCList, but it's still useful separately.)
   1.184 + */
   1.185 +
   1.186 +class nsLineLink {
   1.187 +
   1.188 +  public:
   1.189 +    friend class nsLineList;
   1.190 +    friend class nsLineList_iterator;
   1.191 +    friend class nsLineList_reverse_iterator;
   1.192 +    friend class nsLineList_const_iterator;
   1.193 +    friend class nsLineList_const_reverse_iterator;
   1.194 +
   1.195 +  private:
   1.196 +    nsLineLink *_mNext; // or head
   1.197 +    nsLineLink *_mPrev; // or tail
   1.198 +
   1.199 +};
   1.200 +
   1.201 +
   1.202 +/**
   1.203 + * The nsLineBox class represents a horizontal line of frames. It contains
   1.204 + * enough state to support incremental reflow of the frames, event handling
   1.205 + * for the frames, and rendering of the frames.
   1.206 + */
   1.207 +class nsLineBox MOZ_FINAL : public nsLineLink {
   1.208 +private:
   1.209 +  nsLineBox(nsIFrame* aFrame, int32_t aCount, bool aIsBlock);
   1.210 +  ~nsLineBox();
   1.211 +  
   1.212 +  // Overloaded new operator. Uses an arena (which comes from the presShell)
   1.213 +  // to perform the allocation.
   1.214 +  void* operator new(size_t sz, nsIPresShell* aPresShell) CPP_THROW_NEW;
   1.215 +  void operator delete(void* aPtr, size_t sz) MOZ_DELETE;
   1.216 +
   1.217 +public:
   1.218 +  // Use these functions to allocate and destroy line boxes
   1.219 +  friend nsLineBox* NS_NewLineBox(nsIPresShell* aPresShell, nsIFrame* aFrame,
   1.220 +                                  bool aIsBlock);
   1.221 +  friend nsLineBox* NS_NewLineBox(nsIPresShell* aPresShell, nsLineBox* aFromLine,
   1.222 +                                  nsIFrame* aFrame, int32_t aCount);
   1.223 +  void Destroy(nsIPresShell* aPresShell);
   1.224 +
   1.225 +  // mBlock bit
   1.226 +  bool IsBlock() const {
   1.227 +    return mFlags.mBlock;
   1.228 +  }
   1.229 +  bool IsInline() const {
   1.230 +    return 0 == mFlags.mBlock;
   1.231 +  }
   1.232 +
   1.233 +  // mDirty bit
   1.234 +  void MarkDirty() {
   1.235 +    mFlags.mDirty = 1;
   1.236 +  }
   1.237 +  void ClearDirty() {
   1.238 +    mFlags.mDirty = 0;
   1.239 +  }
   1.240 +  bool IsDirty() const {
   1.241 +    return mFlags.mDirty;
   1.242 +  }
   1.243 +
   1.244 +  // mPreviousMarginDirty bit
   1.245 +  void MarkPreviousMarginDirty() {
   1.246 +    mFlags.mPreviousMarginDirty = 1;
   1.247 +  }
   1.248 +  void ClearPreviousMarginDirty() {
   1.249 +    mFlags.mPreviousMarginDirty = 0;
   1.250 +  }
   1.251 +  bool IsPreviousMarginDirty() const {
   1.252 +    return mFlags.mPreviousMarginDirty;
   1.253 +  }
   1.254 +
   1.255 +  // mHasClearance bit
   1.256 +  void SetHasClearance() {
   1.257 +    mFlags.mHasClearance = 1;
   1.258 +  }
   1.259 +  void ClearHasClearance() {
   1.260 +    mFlags.mHasClearance = 0;
   1.261 +  }
   1.262 +  bool HasClearance() const {
   1.263 +    return mFlags.mHasClearance;
   1.264 +  }
   1.265 +
   1.266 +  // mImpactedByFloat bit
   1.267 +  void SetLineIsImpactedByFloat(bool aValue) {
   1.268 +    mFlags.mImpactedByFloat = aValue;
   1.269 +  }
   1.270 +  bool IsImpactedByFloat() const {
   1.271 +    return mFlags.mImpactedByFloat;
   1.272 +  }
   1.273 +
   1.274 +  // mLineWrapped bit
   1.275 +  void SetLineWrapped(bool aOn) {
   1.276 +    mFlags.mLineWrapped = aOn;
   1.277 +  }
   1.278 +  bool IsLineWrapped() const {
   1.279 +    return mFlags.mLineWrapped;
   1.280 +  }
   1.281 +
   1.282 +  // mInvalidateTextRuns bit
   1.283 +  void SetInvalidateTextRuns(bool aOn) {
   1.284 +    mFlags.mInvalidateTextRuns = aOn;
   1.285 +  }
   1.286 +  bool GetInvalidateTextRuns() const {
   1.287 +    return mFlags.mInvalidateTextRuns;
   1.288 +  }
   1.289 +
   1.290 +  // mResizeReflowOptimizationDisabled bit
   1.291 +  void DisableResizeReflowOptimization() {
   1.292 +    mFlags.mResizeReflowOptimizationDisabled = true;
   1.293 +  }
   1.294 +  void EnableResizeReflowOptimization() {
   1.295 +    mFlags.mResizeReflowOptimizationDisabled = false;
   1.296 +  }
   1.297 +  bool ResizeReflowOptimizationDisabled() const {
   1.298 +    return mFlags.mResizeReflowOptimizationDisabled;
   1.299 +  }
   1.300 +
   1.301 +  // mHasBullet bit
   1.302 +  void SetHasBullet() {
   1.303 +    mFlags.mHasBullet = true;
   1.304 +    InvalidateCachedIsEmpty();
   1.305 +  }
   1.306 +  void ClearHasBullet() {
   1.307 +    mFlags.mHasBullet = false;
   1.308 +    InvalidateCachedIsEmpty();
   1.309 +  }
   1.310 +  bool HasBullet() const {
   1.311 +    return mFlags.mHasBullet;
   1.312 +  }
   1.313 +
   1.314 +  // mHadFloatPushed bit
   1.315 +  void SetHadFloatPushed() {
   1.316 +    mFlags.mHadFloatPushed = true;
   1.317 +  }
   1.318 +  void ClearHadFloatPushed() {
   1.319 +    mFlags.mHadFloatPushed = false;
   1.320 +  }
   1.321 +  bool HadFloatPushed() const {
   1.322 +    return mFlags.mHadFloatPushed;
   1.323 +  }
   1.324 +
   1.325 +private:
   1.326 +  // Add a hash table for fast lookup when the line has more frames than this.
   1.327 +  static const uint32_t kMinChildCountForHashtable = 200;
   1.328 +
   1.329 +  /**
   1.330 +   * Take ownership of aFromLine's hash table and remove the frames that
   1.331 +   * stay on aFromLine from it, i.e. aFromLineNewCount frames starting with
   1.332 +   * mFirstChild.  This method is used to optimize moving a large number
   1.333 +   * of frames from one line to the next.
   1.334 +   */
   1.335 +  void StealHashTableFrom(nsLineBox* aFromLine, uint32_t aFromLineNewCount);
   1.336 +
   1.337 +  /**
   1.338 +   * Does the equivalent of this->NoteFrameAdded and aFromLine->NoteFrameRemoved
   1.339 +   * for each frame on this line, but in a optimized way.
   1.340 +   */
   1.341 +  void NoteFramesMovedFrom(nsLineBox* aFromLine);
   1.342 +
   1.343 +  void SwitchToHashtable()
   1.344 +  {
   1.345 +    MOZ_ASSERT(!mFlags.mHasHashedFrames);
   1.346 +    uint32_t count = GetChildCount();
   1.347 +    mFlags.mHasHashedFrames = 1;
   1.348 +    uint32_t minSize =
   1.349 +      std::max(kMinChildCountForHashtable, uint32_t(PL_DHASH_MIN_SIZE));
   1.350 +    mFrames = new nsTHashtable< nsPtrHashKey<nsIFrame> >(std::max(count, minSize));
   1.351 +    for (nsIFrame* f = mFirstChild; count-- > 0; f = f->GetNextSibling()) {
   1.352 +      mFrames->PutEntry(f);
   1.353 +    }
   1.354 +  }
   1.355 +  void SwitchToCounter() {
   1.356 +    MOZ_ASSERT(mFlags.mHasHashedFrames);
   1.357 +    uint32_t count = GetChildCount();
   1.358 +    delete mFrames;
   1.359 +    mFlags.mHasHashedFrames = 0;
   1.360 +    mChildCount = count;
   1.361 +  }
   1.362 +
   1.363 +public:
   1.364 +  int32_t GetChildCount() const {
   1.365 +    return MOZ_UNLIKELY(mFlags.mHasHashedFrames) ? mFrames->Count() : mChildCount;
   1.366 +  }
   1.367 +
   1.368 +  /**
   1.369 +   * Register that aFrame is now on this line.
   1.370 +   */
   1.371 +  void NoteFrameAdded(nsIFrame* aFrame) {
   1.372 +    if (MOZ_UNLIKELY(mFlags.mHasHashedFrames)) {
   1.373 +      mFrames->PutEntry(aFrame);
   1.374 +    } else {
   1.375 +      if (++mChildCount >= kMinChildCountForHashtable) {
   1.376 +        SwitchToHashtable();
   1.377 +      }
   1.378 +    }
   1.379 +  }
   1.380 +
   1.381 +  /**
   1.382 +   * Register that aFrame is not on this line anymore.
   1.383 +   */
   1.384 +  void NoteFrameRemoved(nsIFrame* aFrame) {
   1.385 +    MOZ_ASSERT(GetChildCount() > 0);
   1.386 +    if (MOZ_UNLIKELY(mFlags.mHasHashedFrames)) {
   1.387 +      mFrames->RemoveEntry(aFrame);
   1.388 +      if (mFrames->Count() < kMinChildCountForHashtable) {
   1.389 +        SwitchToCounter();
   1.390 +      }
   1.391 +    } else {
   1.392 +      --mChildCount;
   1.393 +    }
   1.394 +  }
   1.395 +
   1.396 +  // mBreakType value
   1.397 +  // Break information is applied *before* the line if the line is a block,
   1.398 +  // or *after* the line if the line is an inline. Confusing, I know, but
   1.399 +  // using different names should help.
   1.400 +  bool HasBreakBefore() const {
   1.401 +    return IsBlock() && NS_STYLE_CLEAR_NONE != mFlags.mBreakType;
   1.402 +  }
   1.403 +  void SetBreakTypeBefore(uint8_t aBreakType) {
   1.404 +    NS_ASSERTION(IsBlock(), "Only blocks have break-before");
   1.405 +    NS_ASSERTION(aBreakType == NS_STYLE_CLEAR_NONE ||
   1.406 +                 aBreakType == NS_STYLE_CLEAR_LEFT ||
   1.407 +                 aBreakType == NS_STYLE_CLEAR_RIGHT ||
   1.408 +                 aBreakType == NS_STYLE_CLEAR_BOTH,
   1.409 +                 "Only float break types are allowed before a line");
   1.410 +    mFlags.mBreakType = aBreakType;
   1.411 +  }
   1.412 +  uint8_t GetBreakTypeBefore() const {
   1.413 +    return IsBlock() ? mFlags.mBreakType : NS_STYLE_CLEAR_NONE;
   1.414 +  }
   1.415 +
   1.416 +  bool HasBreakAfter() const {
   1.417 +    return !IsBlock() && NS_STYLE_CLEAR_NONE != mFlags.mBreakType;
   1.418 +  }
   1.419 +  void SetBreakTypeAfter(uint8_t aBreakType) {
   1.420 +    NS_ASSERTION(!IsBlock(), "Only inlines have break-after");
   1.421 +    NS_ASSERTION(aBreakType <= LINE_MAX_BREAK_TYPE, "bad break type");
   1.422 +    mFlags.mBreakType = aBreakType;
   1.423 +  }
   1.424 +  bool HasFloatBreakAfter() const {
   1.425 +    return !IsBlock() && (NS_STYLE_CLEAR_LEFT == mFlags.mBreakType ||
   1.426 +                          NS_STYLE_CLEAR_RIGHT == mFlags.mBreakType ||
   1.427 +                          NS_STYLE_CLEAR_BOTH == mFlags.mBreakType);
   1.428 +  }
   1.429 +  uint8_t GetBreakTypeAfter() const {
   1.430 +    return !IsBlock() ? mFlags.mBreakType : NS_STYLE_CLEAR_NONE;
   1.431 +  }
   1.432 +
   1.433 +  // mCarriedOutBottomMargin value
   1.434 +  nsCollapsingMargin GetCarriedOutBottomMargin() const;
   1.435 +  // Returns true if the margin changed
   1.436 +  bool SetCarriedOutBottomMargin(nsCollapsingMargin aValue);
   1.437 +
   1.438 +  // mFloats
   1.439 +  bool HasFloats() const {
   1.440 +    return (IsInline() && mInlineData) && mInlineData->mFloats.NotEmpty();
   1.441 +  }
   1.442 +  nsFloatCache* GetFirstFloat();
   1.443 +  void FreeFloats(nsFloatCacheFreeList& aFreeList);
   1.444 +  void AppendFloats(nsFloatCacheFreeList& aFreeList);
   1.445 +  bool RemoveFloat(nsIFrame* aFrame);
   1.446 +
   1.447 +  // Combined area is the area of the line that should influence the
   1.448 +  // overflow area of its parent block.  The combined area should be
   1.449 +  // used for painting-related things, but should never be used for
   1.450 +  // layout (except for handling of 'overflow').
   1.451 +  void SetOverflowAreas(const nsOverflowAreas& aOverflowAreas);
   1.452 +  nsRect GetOverflowArea(nsOverflowType aType) {
   1.453 +    return mData ? mData->mOverflowAreas.Overflow(aType) : GetPhysicalBounds();
   1.454 +  }
   1.455 +  nsOverflowAreas GetOverflowAreas() {
   1.456 +    if (mData) {
   1.457 +      return mData->mOverflowAreas;
   1.458 +    }
   1.459 +    nsRect bounds = GetPhysicalBounds();
   1.460 +    return nsOverflowAreas(bounds, bounds);
   1.461 +  }
   1.462 +  nsRect GetVisualOverflowArea()
   1.463 +    { return GetOverflowArea(eVisualOverflow); }
   1.464 +  nsRect GetScrollableOverflowArea()
   1.465 +    { return GetOverflowArea(eScrollableOverflow); }
   1.466 +
   1.467 +  void SlideBy(nscoord aDBCoord, nscoord aContainerWidth) {
   1.468 +    NS_ASSERTION(aContainerWidth == mContainerWidth || mContainerWidth == -1,
   1.469 +                 "container width doesn't match");
   1.470 +    mContainerWidth = aContainerWidth;
   1.471 +    mBounds.BStart(mWritingMode) += aDBCoord;
   1.472 +    if (mData) {
   1.473 +      NS_FOR_FRAME_OVERFLOW_TYPES(otype) {
   1.474 +        mData->mOverflowAreas.Overflow(otype).y += aDBCoord;
   1.475 +      }
   1.476 +    }
   1.477 +  }
   1.478 +
   1.479 +  void IndentBy(nscoord aDICoord, nscoord aContainerWidth) {
   1.480 +    NS_ASSERTION(aContainerWidth == mContainerWidth || mContainerWidth == -1,
   1.481 +                 "container width doesn't match");
   1.482 +    mContainerWidth = aContainerWidth;
   1.483 +    mBounds.IStart(mWritingMode) += aDICoord;
   1.484 +  }
   1.485 +
   1.486 +  void ExpandBy(nscoord aDISize, nscoord aContainerWidth) {
   1.487 +    NS_ASSERTION(aContainerWidth == mContainerWidth || mContainerWidth == -1,
   1.488 +                 "container width doesn't match");
   1.489 +    mContainerWidth = aContainerWidth;
   1.490 +    mBounds.ISize(mWritingMode) += aDISize;
   1.491 +  }
   1.492 +
   1.493 +  /**
   1.494 +   * The ascent (distance from top to baseline) of the linebox is the
   1.495 +   * ascent of the anonymous inline box (for which we don't actually
   1.496 +   * create a frame) that wraps all the consecutive inline children of a
   1.497 +   * block.
   1.498 +   *
   1.499 +   * This is currently unused for block lines.
   1.500 +   */
   1.501 +  nscoord GetAscent() const { return mAscent; }
   1.502 +  void SetAscent(nscoord aAscent) { mAscent = aAscent; }
   1.503 +
   1.504 +  nscoord BStart() const {
   1.505 +    return mBounds.BStart(mWritingMode);
   1.506 +  }
   1.507 +  nscoord BSize() const {
   1.508 +    return mBounds.BSize(mWritingMode);
   1.509 +  }
   1.510 +  nscoord BEnd() const {
   1.511 +    return mBounds.BEnd(mWritingMode);
   1.512 +  }
   1.513 +  nscoord IStart() const {
   1.514 +    return mBounds.IStart(mWritingMode);
   1.515 +  }
   1.516 +  nscoord ISize() const {
   1.517 +    return mBounds.ISize(mWritingMode);
   1.518 +  }
   1.519 +  nscoord IEnd() const {
   1.520 +    return mBounds.IEnd(mWritingMode);
   1.521 +  }
   1.522 +  void SetBoundsEmpty() {
   1.523 +    mBounds.IStart(mWritingMode) = 0;
   1.524 +    mBounds.ISize(mWritingMode) = 0;
   1.525 +    mBounds.BStart(mWritingMode) = 0;
   1.526 +    mBounds.BSize(mWritingMode) = 0;
   1.527 +  }
   1.528 +
   1.529 +  static void DeleteLineList(nsPresContext* aPresContext, nsLineList& aLines,
   1.530 +                             nsIFrame* aDestructRoot, nsFrameList* aFrames);
   1.531 +
   1.532 +  // search from end to beginning of [aBegin, aEnd)
   1.533 +  // Returns true if it found the line and false if not.
   1.534 +  // Moves aEnd as it searches so that aEnd points to the resulting line.
   1.535 +  // aLastFrameBeforeEnd is the last frame before aEnd (so if aEnd is
   1.536 +  // the end of the line list, it's just the last frame in the frame
   1.537 +  // list).
   1.538 +  static bool RFindLineContaining(nsIFrame* aFrame,
   1.539 +                                    const nsLineList_iterator& aBegin,
   1.540 +                                    nsLineList_iterator& aEnd,
   1.541 +                                    nsIFrame* aLastFrameBeforeEnd,
   1.542 +                                    int32_t* aFrameIndexInLine);
   1.543 +
   1.544 +#ifdef DEBUG_FRAME_DUMP
   1.545 +  char* StateToString(char* aBuf, int32_t aBufSize) const;
   1.546 +
   1.547 +  void List(FILE* out, int32_t aIndent, uint32_t aFlags = 0) const;
   1.548 +  void List(FILE* out = stderr, const char* aPrefix = "", uint32_t aFlags = 0) const;
   1.549 +  nsIFrame* LastChild() const;
   1.550 +#endif
   1.551 +
   1.552 +private:
   1.553 +  int32_t IndexOf(nsIFrame* aFrame) const;
   1.554 +public:
   1.555 +
   1.556 +  bool Contains(nsIFrame* aFrame) const {
   1.557 +    return MOZ_UNLIKELY(mFlags.mHasHashedFrames) ? mFrames->Contains(aFrame)
   1.558 +                                                : IndexOf(aFrame) >= 0;
   1.559 +  }
   1.560 +
   1.561 +  // whether the line box is "logically" empty (just like nsIFrame::IsEmpty)
   1.562 +  bool IsEmpty() const;
   1.563 +
   1.564 +  // Call this only while in Reflow() for the block the line belongs
   1.565 +  // to, only between reflowing the line (or sliding it, if we skip
   1.566 +  // reflowing it) and the end of reflowing the block.
   1.567 +  bool CachedIsEmpty();
   1.568 +
   1.569 +  void InvalidateCachedIsEmpty() {
   1.570 +    mFlags.mEmptyCacheValid = false;
   1.571 +  }
   1.572 +
   1.573 +  // For debugging purposes
   1.574 +  bool IsValidCachedIsEmpty() {
   1.575 +    return mFlags.mEmptyCacheValid;
   1.576 +  }
   1.577 +
   1.578 +#ifdef DEBUG
   1.579 +  static int32_t GetCtorCount();
   1.580 +#endif
   1.581 +
   1.582 +  nsIFrame* mFirstChild;
   1.583 +
   1.584 +  mozilla::WritingMode mWritingMode;
   1.585 +  nscoord mContainerWidth;
   1.586 + private:
   1.587 +  mozilla::LogicalRect mBounds;
   1.588 + public:
   1.589 +  const mozilla::LogicalRect& GetBounds() { return mBounds; }
   1.590 +  nsRect GetPhysicalBounds() const
   1.591 +  {
   1.592 +    if (mBounds.IsEmpty()) {
   1.593 +      return nsRect(0, 0, 0, 0);
   1.594 +    }
   1.595 +
   1.596 +    NS_ASSERTION(mContainerWidth != -1, "mContainerWidth not initialized");
   1.597 +    return mBounds.GetPhysicalRect(mWritingMode, mContainerWidth);
   1.598 +  }
   1.599 +  void SetBounds(mozilla::WritingMode aWritingMode,
   1.600 +                 nscoord aIStart, nscoord aBStart,
   1.601 +                 nscoord aISize, nscoord aBSize,
   1.602 +                 nscoord aContainerWidth)
   1.603 +  {
   1.604 +    mWritingMode = aWritingMode;
   1.605 +    mContainerWidth = aContainerWidth;
   1.606 +    mBounds = mozilla::LogicalRect(aWritingMode, aIStart, aBStart,
   1.607 +                                   aISize, aBSize);
   1.608 +  }
   1.609 +  void SetBounds(mozilla::WritingMode aWritingMode,
   1.610 +                 nsRect aRect, nscoord aContainerWidth)
   1.611 +  {
   1.612 +    mWritingMode = aWritingMode;
   1.613 +    mContainerWidth = aContainerWidth;
   1.614 +    mBounds = mozilla::LogicalRect(aWritingMode, aRect, aContainerWidth);
   1.615 +  }
   1.616 +
   1.617 +  // mFlags.mHasHashedFrames says which one to use
   1.618 +  union {
   1.619 +    nsTHashtable< nsPtrHashKey<nsIFrame> >* mFrames;
   1.620 +    uint32_t mChildCount;
   1.621 +  };
   1.622 +
   1.623 +  struct FlagBits {
   1.624 +    uint32_t mDirty : 1;
   1.625 +    uint32_t mPreviousMarginDirty : 1;
   1.626 +    uint32_t mHasClearance : 1;
   1.627 +    uint32_t mBlock : 1;
   1.628 +    uint32_t mImpactedByFloat : 1;
   1.629 +    uint32_t mLineWrapped: 1;
   1.630 +    uint32_t mInvalidateTextRuns : 1;
   1.631 +    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
   1.632 +    uint32_t mEmptyCacheValid: 1;
   1.633 +    uint32_t mEmptyCacheState: 1;
   1.634 +    // mHasBullet indicates that this is an inline line whose block's
   1.635 +    // bullet is adjacent to this line and non-empty.
   1.636 +    uint32_t mHasBullet : 1;
   1.637 +    // Indicates that this line *may* have a placeholder for a float
   1.638 +    // that was pushed to a later column or page.
   1.639 +    uint32_t mHadFloatPushed : 1;
   1.640 +    uint32_t mHasHashedFrames: 1;
   1.641 +    uint32_t mBreakType : 4;
   1.642 +  };
   1.643 +
   1.644 +  struct ExtraData {
   1.645 +    ExtraData(const nsRect& aBounds) : mOverflowAreas(aBounds, aBounds) {
   1.646 +    }
   1.647 +    nsOverflowAreas mOverflowAreas;
   1.648 +  };
   1.649 +
   1.650 +  struct ExtraBlockData : public ExtraData {
   1.651 +    ExtraBlockData(const nsRect& aBounds)
   1.652 +      : ExtraData(aBounds),
   1.653 +        mCarriedOutBottomMargin()
   1.654 +    {
   1.655 +    }
   1.656 +    nsCollapsingMargin mCarriedOutBottomMargin;
   1.657 +  };
   1.658 +
   1.659 +  struct ExtraInlineData : public ExtraData {
   1.660 +    ExtraInlineData(const nsRect& aBounds) : ExtraData(aBounds) {
   1.661 +    }
   1.662 +    nsFloatCacheList mFloats;
   1.663 +  };
   1.664 +
   1.665 +protected:
   1.666 +  nscoord mAscent;           // see |SetAscent| / |GetAscent|
   1.667 +  union {
   1.668 +    uint32_t mAllFlags;
   1.669 +    FlagBits mFlags;
   1.670 +  };
   1.671 +
   1.672 +  union {
   1.673 +    ExtraData* mData;
   1.674 +    ExtraBlockData* mBlockData;
   1.675 +    ExtraInlineData* mInlineData;
   1.676 +  };
   1.677 +
   1.678 +  void Cleanup();
   1.679 +  void MaybeFreeData();
   1.680 +};
   1.681 +
   1.682 +/**
   1.683 + * A linked list type where the items in the list must inherit from
   1.684 + * a link type to fuse allocations.
   1.685 + *
   1.686 + * API heavily based on the |list| class in the C++ standard.
   1.687 + */
   1.688 + 
   1.689 +class nsLineList_iterator {
   1.690 +  public:
   1.691 +    friend class nsLineList;
   1.692 +    friend class nsLineList_reverse_iterator;
   1.693 +    friend class nsLineList_const_iterator;
   1.694 +    friend class nsLineList_const_reverse_iterator;
   1.695 +
   1.696 +    typedef nsLineList_iterator         iterator_self_type;
   1.697 +    typedef nsLineList_reverse_iterator iterator_reverse_type;
   1.698 +
   1.699 +    typedef nsLineBox&                  reference;
   1.700 +    typedef const nsLineBox&            const_reference;
   1.701 +
   1.702 +    typedef nsLineBox*                  pointer;
   1.703 +    typedef const nsLineBox*            const_pointer;
   1.704 +
   1.705 +    typedef uint32_t                    size_type;
   1.706 +    typedef int32_t                     difference_type;
   1.707 +
   1.708 +    typedef nsLineLink                  link_type;
   1.709 +
   1.710 +#ifdef DEBUG
   1.711 +    nsLineList_iterator() { memset(&mCurrent, 0xcd, sizeof(mCurrent)); }
   1.712 +#else
   1.713 +    // Auto generated default constructor OK.
   1.714 +#endif
   1.715 +    // Auto generated copy-constructor OK.
   1.716 +
   1.717 +    inline iterator_self_type&
   1.718 +        operator=(const iterator_self_type& aOther);
   1.719 +    inline iterator_self_type&
   1.720 +        operator=(const iterator_reverse_type& aOther);
   1.721 +
   1.722 +    iterator_self_type& operator++()
   1.723 +    {
   1.724 +      mCurrent = mCurrent->_mNext;
   1.725 +      return *this;
   1.726 +    }
   1.727 +
   1.728 +    iterator_self_type operator++(int)
   1.729 +    {
   1.730 +      iterator_self_type rv(*this);
   1.731 +      mCurrent = mCurrent->_mNext;
   1.732 +      return rv;
   1.733 +    }
   1.734 +
   1.735 +    iterator_self_type& operator--()
   1.736 +    {
   1.737 +      mCurrent = mCurrent->_mPrev;
   1.738 +      return *this;
   1.739 +    }
   1.740 +
   1.741 +    iterator_self_type operator--(int)
   1.742 +    {
   1.743 +      iterator_self_type rv(*this);
   1.744 +      mCurrent = mCurrent->_mPrev;
   1.745 +      return rv;
   1.746 +    }
   1.747 +
   1.748 +    reference operator*()
   1.749 +    {
   1.750 +      NS_ABORT_IF_FALSE(mCurrent != mListLink, "running past end");
   1.751 +      return *static_cast<pointer>(mCurrent);
   1.752 +    }
   1.753 +
   1.754 +    pointer operator->()
   1.755 +    {
   1.756 +      NS_ABORT_IF_FALSE(mCurrent != mListLink, "running past end");
   1.757 +      return static_cast<pointer>(mCurrent);
   1.758 +    }
   1.759 +
   1.760 +    pointer get()
   1.761 +    {
   1.762 +      NS_ABORT_IF_FALSE(mCurrent != mListLink, "running past end");
   1.763 +      return static_cast<pointer>(mCurrent);
   1.764 +    }
   1.765 +
   1.766 +    operator pointer()
   1.767 +    {
   1.768 +      NS_ABORT_IF_FALSE(mCurrent != mListLink, "running past end");
   1.769 +      return static_cast<pointer>(mCurrent);
   1.770 +    }
   1.771 +
   1.772 +    const_reference operator*() const
   1.773 +    {
   1.774 +      NS_ABORT_IF_FALSE(mCurrent != mListLink, "running past end");
   1.775 +      return *static_cast<const_pointer>(mCurrent);
   1.776 +    }
   1.777 +
   1.778 +    const_pointer operator->() const
   1.779 +    {
   1.780 +      NS_ABORT_IF_FALSE(mCurrent != mListLink, "running past end");
   1.781 +      return static_cast<const_pointer>(mCurrent);
   1.782 +    }
   1.783 +
   1.784 +#ifndef __MWERKS__
   1.785 +    operator const_pointer() const
   1.786 +    {
   1.787 +      NS_ABORT_IF_FALSE(mCurrent != mListLink, "running past end");
   1.788 +      return static_cast<const_pointer>(mCurrent);
   1.789 +    }
   1.790 +#endif /* !__MWERKS__ */
   1.791 +
   1.792 +    iterator_self_type next()
   1.793 +    {
   1.794 +      iterator_self_type copy(*this);
   1.795 +      return ++copy;
   1.796 +    }
   1.797 +
   1.798 +    const iterator_self_type next() const
   1.799 +    {
   1.800 +      iterator_self_type copy(*this);
   1.801 +      return ++copy;
   1.802 +    }
   1.803 +
   1.804 +    iterator_self_type prev()
   1.805 +    {
   1.806 +      iterator_self_type copy(*this);
   1.807 +      return --copy;
   1.808 +    }
   1.809 +
   1.810 +    const iterator_self_type prev() const
   1.811 +    {
   1.812 +      iterator_self_type copy(*this);
   1.813 +      return --copy;
   1.814 +    }
   1.815 +
   1.816 +    // Passing by value rather than by reference and reference to const
   1.817 +    // to keep AIX happy.
   1.818 +    bool operator==(const iterator_self_type aOther) const
   1.819 +    {
   1.820 +      NS_ABORT_IF_FALSE(mListLink == aOther.mListLink, "comparing iterators over different lists");
   1.821 +      return mCurrent == aOther.mCurrent;
   1.822 +    }
   1.823 +    bool operator!=(const iterator_self_type aOther) const
   1.824 +    {
   1.825 +      NS_ABORT_IF_FALSE(mListLink == aOther.mListLink, "comparing iterators over different lists");
   1.826 +      return mCurrent != aOther.mCurrent;
   1.827 +    }
   1.828 +    bool operator==(const iterator_self_type aOther)
   1.829 +    {
   1.830 +      NS_ABORT_IF_FALSE(mListLink == aOther.mListLink, "comparing iterators over different lists");
   1.831 +      return mCurrent == aOther.mCurrent;
   1.832 +    }
   1.833 +    bool operator!=(const iterator_self_type aOther)
   1.834 +    {
   1.835 +      NS_ABORT_IF_FALSE(mListLink == aOther.mListLink, "comparing iterators over different lists");
   1.836 +      return mCurrent != aOther.mCurrent;
   1.837 +    }
   1.838 +
   1.839 +  private:
   1.840 +    link_type *mCurrent;
   1.841 +#ifdef DEBUG
   1.842 +    link_type *mListLink; // the list's link, i.e., the end
   1.843 +#endif
   1.844 +};
   1.845 +
   1.846 +class nsLineList_reverse_iterator {
   1.847 +
   1.848 +  public:
   1.849 +
   1.850 +    friend class nsLineList;
   1.851 +    friend class nsLineList_iterator;
   1.852 +    friend class nsLineList_const_iterator;
   1.853 +    friend class nsLineList_const_reverse_iterator;
   1.854 +
   1.855 +    typedef nsLineList_reverse_iterator iterator_self_type;
   1.856 +    typedef nsLineList_iterator         iterator_reverse_type;
   1.857 +
   1.858 +    typedef nsLineBox&                  reference;
   1.859 +    typedef const nsLineBox&            const_reference;
   1.860 +
   1.861 +    typedef nsLineBox*                  pointer;
   1.862 +    typedef const nsLineBox*            const_pointer;
   1.863 +
   1.864 +    typedef uint32_t                    size_type;
   1.865 +    typedef int32_t                     difference_type;
   1.866 +
   1.867 +    typedef nsLineLink                  link_type;
   1.868 +
   1.869 +#ifdef DEBUG
   1.870 +    nsLineList_reverse_iterator() { memset(&mCurrent, 0xcd, sizeof(mCurrent)); }
   1.871 +#else
   1.872 +    // Auto generated default constructor OK.
   1.873 +#endif
   1.874 +    // Auto generated copy-constructor OK.
   1.875 +
   1.876 +    inline iterator_self_type&
   1.877 +        operator=(const iterator_reverse_type& aOther);
   1.878 +    inline iterator_self_type&
   1.879 +        operator=(const iterator_self_type& aOther);
   1.880 +
   1.881 +    iterator_self_type& operator++()
   1.882 +    {
   1.883 +      mCurrent = mCurrent->_mPrev;
   1.884 +      return *this;
   1.885 +    }
   1.886 +
   1.887 +    iterator_self_type operator++(int)
   1.888 +    {
   1.889 +      iterator_self_type rv(*this);
   1.890 +      mCurrent = mCurrent->_mPrev;
   1.891 +      return rv;
   1.892 +    }
   1.893 +
   1.894 +    iterator_self_type& operator--()
   1.895 +    {
   1.896 +      mCurrent = mCurrent->_mNext;
   1.897 +      return *this;
   1.898 +    }
   1.899 +
   1.900 +    iterator_self_type operator--(int)
   1.901 +    {
   1.902 +      iterator_self_type rv(*this);
   1.903 +      mCurrent = mCurrent->_mNext;
   1.904 +      return rv;
   1.905 +    }
   1.906 +
   1.907 +    reference operator*()
   1.908 +    {
   1.909 +      NS_ABORT_IF_FALSE(mCurrent != mListLink, "running past end");
   1.910 +      return *static_cast<pointer>(mCurrent);
   1.911 +    }
   1.912 +
   1.913 +    pointer operator->()
   1.914 +    {
   1.915 +      NS_ABORT_IF_FALSE(mCurrent != mListLink, "running past end");
   1.916 +      return static_cast<pointer>(mCurrent);
   1.917 +    }
   1.918 +
   1.919 +    pointer get()
   1.920 +    {
   1.921 +      NS_ABORT_IF_FALSE(mCurrent != mListLink, "running past end");
   1.922 +      return static_cast<pointer>(mCurrent);
   1.923 +    }
   1.924 +
   1.925 +    operator pointer()
   1.926 +    {
   1.927 +      NS_ABORT_IF_FALSE(mCurrent != mListLink, "running past end");
   1.928 +      return static_cast<pointer>(mCurrent);
   1.929 +    }
   1.930 +
   1.931 +    const_reference operator*() const
   1.932 +    {
   1.933 +      NS_ABORT_IF_FALSE(mCurrent != mListLink, "running past end");
   1.934 +      return *static_cast<const_pointer>(mCurrent);
   1.935 +    }
   1.936 +
   1.937 +    const_pointer operator->() const
   1.938 +    {
   1.939 +      NS_ABORT_IF_FALSE(mCurrent != mListLink, "running past end");
   1.940 +      return static_cast<const_pointer>(mCurrent);
   1.941 +    }
   1.942 +
   1.943 +#ifndef __MWERKS__
   1.944 +    operator const_pointer() const
   1.945 +    {
   1.946 +      NS_ABORT_IF_FALSE(mCurrent != mListLink, "running past end");
   1.947 +      return static_cast<const_pointer>(mCurrent);
   1.948 +    }
   1.949 +#endif /* !__MWERKS__ */
   1.950 +
   1.951 +    // Passing by value rather than by reference and reference to const
   1.952 +    // to keep AIX happy.
   1.953 +    bool operator==(const iterator_self_type aOther) const
   1.954 +    {
   1.955 +      NS_ASSERTION(mListLink == aOther.mListLink, "comparing iterators over different lists");
   1.956 +      return mCurrent == aOther.mCurrent;
   1.957 +    }
   1.958 +    bool operator!=(const iterator_self_type aOther) const
   1.959 +    {
   1.960 +      NS_ASSERTION(mListLink == aOther.mListLink, "comparing iterators over different lists");
   1.961 +      return mCurrent != aOther.mCurrent;
   1.962 +    }
   1.963 +    bool operator==(const iterator_self_type aOther)
   1.964 +    {
   1.965 +      NS_ASSERTION(mListLink == aOther.mListLink, "comparing iterators over different lists");
   1.966 +      return mCurrent == aOther.mCurrent;
   1.967 +    }
   1.968 +    bool operator!=(const iterator_self_type aOther)
   1.969 +    {
   1.970 +      NS_ASSERTION(mListLink == aOther.mListLink, "comparing iterators over different lists");
   1.971 +      return mCurrent != aOther.mCurrent;
   1.972 +    }
   1.973 +
   1.974 +  private:
   1.975 +    link_type *mCurrent;
   1.976 +#ifdef DEBUG
   1.977 +    link_type *mListLink; // the list's link, i.e., the end
   1.978 +#endif
   1.979 +};
   1.980 +
   1.981 +class nsLineList_const_iterator {
   1.982 +  public:
   1.983 +
   1.984 +    friend class nsLineList;
   1.985 +    friend class nsLineList_iterator;
   1.986 +    friend class nsLineList_reverse_iterator;
   1.987 +    friend class nsLineList_const_reverse_iterator;
   1.988 +
   1.989 +    typedef nsLineList_const_iterator           iterator_self_type;
   1.990 +    typedef nsLineList_const_reverse_iterator   iterator_reverse_type;
   1.991 +    typedef nsLineList_iterator                 iterator_nonconst_type;
   1.992 +    typedef nsLineList_reverse_iterator         iterator_nonconst_reverse_type;
   1.993 +
   1.994 +    typedef nsLineBox&                  reference;
   1.995 +    typedef const nsLineBox&            const_reference;
   1.996 +
   1.997 +    typedef nsLineBox*                  pointer;
   1.998 +    typedef const nsLineBox*            const_pointer;
   1.999 +
  1.1000 +    typedef uint32_t                    size_type;
  1.1001 +    typedef int32_t                     difference_type;
  1.1002 +
  1.1003 +    typedef nsLineLink                  link_type;
  1.1004 +
  1.1005 +#ifdef DEBUG
  1.1006 +    nsLineList_const_iterator() { memset(&mCurrent, 0xcd, sizeof(mCurrent)); }
  1.1007 +#else
  1.1008 +    // Auto generated default constructor OK.
  1.1009 +#endif
  1.1010 +    // Auto generated copy-constructor OK.
  1.1011 +
  1.1012 +    inline iterator_self_type&
  1.1013 +        operator=(const iterator_nonconst_type& aOther);
  1.1014 +    inline iterator_self_type&
  1.1015 +        operator=(const iterator_nonconst_reverse_type& aOther);
  1.1016 +    inline iterator_self_type&
  1.1017 +        operator=(const iterator_self_type& aOther);
  1.1018 +    inline iterator_self_type&
  1.1019 +        operator=(const iterator_reverse_type& aOther);
  1.1020 +
  1.1021 +    iterator_self_type& operator++()
  1.1022 +    {
  1.1023 +      mCurrent = mCurrent->_mNext;
  1.1024 +      return *this;
  1.1025 +    }
  1.1026 +
  1.1027 +    iterator_self_type operator++(int)
  1.1028 +    {
  1.1029 +      iterator_self_type rv(*this);
  1.1030 +      mCurrent = mCurrent->_mNext;
  1.1031 +      return rv;
  1.1032 +    }
  1.1033 +
  1.1034 +    iterator_self_type& operator--()
  1.1035 +    {
  1.1036 +      mCurrent = mCurrent->_mPrev;
  1.1037 +      return *this;
  1.1038 +    }
  1.1039 +
  1.1040 +    iterator_self_type operator--(int)
  1.1041 +    {
  1.1042 +      iterator_self_type rv(*this);
  1.1043 +      mCurrent = mCurrent->_mPrev;
  1.1044 +      return rv;
  1.1045 +    }
  1.1046 +
  1.1047 +    const_reference operator*() const
  1.1048 +    {
  1.1049 +      NS_ABORT_IF_FALSE(mCurrent != mListLink, "running past end");
  1.1050 +      return *static_cast<const_pointer>(mCurrent);
  1.1051 +    }
  1.1052 +
  1.1053 +    const_pointer operator->() const
  1.1054 +    {
  1.1055 +      NS_ABORT_IF_FALSE(mCurrent != mListLink, "running past end");
  1.1056 +      return static_cast<const_pointer>(mCurrent);
  1.1057 +    }
  1.1058 +
  1.1059 +    const_pointer get() const
  1.1060 +    {
  1.1061 +      NS_ABORT_IF_FALSE(mCurrent != mListLink, "running past end");
  1.1062 +      return static_cast<const_pointer>(mCurrent);
  1.1063 +    }
  1.1064 +
  1.1065 +#ifndef __MWERKS__
  1.1066 +    operator const_pointer() const
  1.1067 +    {
  1.1068 +      NS_ABORT_IF_FALSE(mCurrent != mListLink, "running past end");
  1.1069 +      return static_cast<const_pointer>(mCurrent);
  1.1070 +    }
  1.1071 +#endif /* !__MWERKS__ */
  1.1072 +
  1.1073 +    const iterator_self_type next() const
  1.1074 +    {
  1.1075 +      iterator_self_type copy(*this);
  1.1076 +      return ++copy;
  1.1077 +    }
  1.1078 +
  1.1079 +    const iterator_self_type prev() const
  1.1080 +    {
  1.1081 +      iterator_self_type copy(*this);
  1.1082 +      return --copy;
  1.1083 +    }
  1.1084 +
  1.1085 +    // Passing by value rather than by reference and reference to const
  1.1086 +    // to keep AIX happy.
  1.1087 +    bool operator==(const iterator_self_type aOther) const
  1.1088 +    {
  1.1089 +      NS_ASSERTION(mListLink == aOther.mListLink, "comparing iterators over different lists");
  1.1090 +      return mCurrent == aOther.mCurrent;
  1.1091 +    }
  1.1092 +    bool operator!=(const iterator_self_type aOther) const
  1.1093 +    {
  1.1094 +      NS_ASSERTION(mListLink == aOther.mListLink, "comparing iterators over different lists");
  1.1095 +      return mCurrent != aOther.mCurrent;
  1.1096 +    }
  1.1097 +    bool operator==(const iterator_self_type aOther)
  1.1098 +    {
  1.1099 +      NS_ASSERTION(mListLink == aOther.mListLink, "comparing iterators over different lists");
  1.1100 +      return mCurrent == aOther.mCurrent;
  1.1101 +    }
  1.1102 +    bool operator!=(const iterator_self_type aOther)
  1.1103 +    {
  1.1104 +      NS_ASSERTION(mListLink == aOther.mListLink, "comparing iterators over different lists");
  1.1105 +      return mCurrent != aOther.mCurrent;
  1.1106 +    }
  1.1107 +
  1.1108 +  private:
  1.1109 +    const link_type *mCurrent;
  1.1110 +#ifdef DEBUG
  1.1111 +    const link_type *mListLink; // the list's link, i.e., the end
  1.1112 +#endif
  1.1113 +};
  1.1114 +
  1.1115 +class nsLineList_const_reverse_iterator {
  1.1116 +  public:
  1.1117 +
  1.1118 +    friend class nsLineList;
  1.1119 +    friend class nsLineList_iterator;
  1.1120 +    friend class nsLineList_reverse_iterator;
  1.1121 +    friend class nsLineList_const_iterator;
  1.1122 +
  1.1123 +    typedef nsLineList_const_reverse_iterator   iterator_self_type;
  1.1124 +    typedef nsLineList_const_iterator           iterator_reverse_type;
  1.1125 +    typedef nsLineList_iterator                 iterator_nonconst_reverse_type;
  1.1126 +    typedef nsLineList_reverse_iterator         iterator_nonconst_type;
  1.1127 +
  1.1128 +    typedef nsLineBox&                  reference;
  1.1129 +    typedef const nsLineBox&            const_reference;
  1.1130 +
  1.1131 +    typedef nsLineBox*                  pointer;
  1.1132 +    typedef const nsLineBox*            const_pointer;
  1.1133 +
  1.1134 +    typedef uint32_t                    size_type;
  1.1135 +    typedef int32_t                     difference_type;
  1.1136 +
  1.1137 +    typedef nsLineLink                  link_type;
  1.1138 +
  1.1139 +#ifdef DEBUG
  1.1140 +    nsLineList_const_reverse_iterator() { memset(&mCurrent, 0xcd, sizeof(mCurrent)); }
  1.1141 +#else
  1.1142 +    // Auto generated default constructor OK.
  1.1143 +#endif
  1.1144 +    // Auto generated copy-constructor OK.
  1.1145 +
  1.1146 +    inline iterator_self_type&
  1.1147 +        operator=(const iterator_nonconst_type& aOther);
  1.1148 +    inline iterator_self_type&
  1.1149 +        operator=(const iterator_nonconst_reverse_type& aOther);
  1.1150 +    inline iterator_self_type&
  1.1151 +        operator=(const iterator_self_type& aOther);
  1.1152 +    inline iterator_self_type&
  1.1153 +        operator=(const iterator_reverse_type& aOther);
  1.1154 +
  1.1155 +    iterator_self_type& operator++()
  1.1156 +    {
  1.1157 +      mCurrent = mCurrent->_mPrev;
  1.1158 +      return *this;
  1.1159 +    }
  1.1160 +
  1.1161 +    iterator_self_type operator++(int)
  1.1162 +    {
  1.1163 +      iterator_self_type rv(*this);
  1.1164 +      mCurrent = mCurrent->_mPrev;
  1.1165 +      return rv;
  1.1166 +    }
  1.1167 +
  1.1168 +    iterator_self_type& operator--()
  1.1169 +    {
  1.1170 +      mCurrent = mCurrent->_mNext;
  1.1171 +      return *this;
  1.1172 +    }
  1.1173 +
  1.1174 +    iterator_self_type operator--(int)
  1.1175 +    {
  1.1176 +      iterator_self_type rv(*this);
  1.1177 +      mCurrent = mCurrent->_mNext;
  1.1178 +      return rv;
  1.1179 +    }
  1.1180 +
  1.1181 +    const_reference operator*() const
  1.1182 +    {
  1.1183 +      NS_ABORT_IF_FALSE(mCurrent != mListLink, "running past end");
  1.1184 +      return *static_cast<const_pointer>(mCurrent);
  1.1185 +    }
  1.1186 +
  1.1187 +    const_pointer operator->() const
  1.1188 +    {
  1.1189 +      NS_ABORT_IF_FALSE(mCurrent != mListLink, "running past end");
  1.1190 +      return static_cast<const_pointer>(mCurrent);
  1.1191 +    }
  1.1192 +
  1.1193 +    const_pointer get() const
  1.1194 +    {
  1.1195 +      NS_ABORT_IF_FALSE(mCurrent != mListLink, "running past end");
  1.1196 +      return static_cast<const_pointer>(mCurrent);
  1.1197 +    }
  1.1198 +
  1.1199 +#ifndef __MWERKS__
  1.1200 +    operator const_pointer() const
  1.1201 +    {
  1.1202 +      NS_ABORT_IF_FALSE(mCurrent != mListLink, "running past end");
  1.1203 +      return static_cast<const_pointer>(mCurrent);
  1.1204 +    }
  1.1205 +#endif /* !__MWERKS__ */
  1.1206 +
  1.1207 +    // Passing by value rather than by reference and reference to const
  1.1208 +    // to keep AIX happy.
  1.1209 +    bool operator==(const iterator_self_type aOther) const
  1.1210 +    {
  1.1211 +      NS_ASSERTION(mListLink == aOther.mListLink, "comparing iterators over different lists");
  1.1212 +      return mCurrent == aOther.mCurrent;
  1.1213 +    }
  1.1214 +    bool operator!=(const iterator_self_type aOther) const
  1.1215 +    {
  1.1216 +      NS_ASSERTION(mListLink == aOther.mListLink, "comparing iterators over different lists");
  1.1217 +      return mCurrent != aOther.mCurrent;
  1.1218 +    }
  1.1219 +    bool operator==(const iterator_self_type aOther)
  1.1220 +    {
  1.1221 +      NS_ASSERTION(mListLink == aOther.mListLink, "comparing iterators over different lists");
  1.1222 +      return mCurrent == aOther.mCurrent;
  1.1223 +    }
  1.1224 +    bool operator!=(const iterator_self_type aOther)
  1.1225 +    {
  1.1226 +      NS_ASSERTION(mListLink == aOther.mListLink, "comparing iterators over different lists");
  1.1227 +      return mCurrent != aOther.mCurrent;
  1.1228 +    }
  1.1229 +
  1.1230 +//private:
  1.1231 +    const link_type *mCurrent;
  1.1232 +#ifdef DEBUG
  1.1233 +    const link_type *mListLink; // the list's link, i.e., the end
  1.1234 +#endif
  1.1235 +};
  1.1236 +
  1.1237 +class nsLineList {
  1.1238 +
  1.1239 +  public:
  1.1240 +
  1.1241 +  friend class nsLineList_iterator;
  1.1242 +  friend class nsLineList_reverse_iterator;
  1.1243 +  friend class nsLineList_const_iterator;
  1.1244 +  friend class nsLineList_const_reverse_iterator;
  1.1245 +
  1.1246 +  typedef uint32_t                    size_type;
  1.1247 +  typedef int32_t                     difference_type;
  1.1248 +
  1.1249 +  typedef nsLineLink                  link_type;
  1.1250 +
  1.1251 +  private:
  1.1252 +    link_type mLink;
  1.1253 +
  1.1254 +  public:
  1.1255 +    typedef nsLineList                  self_type;
  1.1256 +
  1.1257 +    typedef nsLineBox&                  reference;
  1.1258 +    typedef const nsLineBox&            const_reference;
  1.1259 +
  1.1260 +    typedef nsLineBox*                  pointer;
  1.1261 +    typedef const nsLineBox*            const_pointer;
  1.1262 +
  1.1263 +    typedef nsLineList_iterator         iterator;
  1.1264 +    typedef nsLineList_reverse_iterator reverse_iterator;
  1.1265 +    typedef nsLineList_const_iterator   const_iterator;
  1.1266 +    typedef nsLineList_const_reverse_iterator const_reverse_iterator;
  1.1267 +
  1.1268 +    nsLineList()
  1.1269 +    {
  1.1270 +      MOZ_COUNT_CTOR(nsLineList);
  1.1271 +      clear();
  1.1272 +    }
  1.1273 +
  1.1274 +    ~nsLineList()
  1.1275 +    {
  1.1276 +      MOZ_COUNT_DTOR(nsLineList);
  1.1277 +    }
  1.1278 +
  1.1279 +    const_iterator begin() const
  1.1280 +    {
  1.1281 +      const_iterator rv;
  1.1282 +      rv.mCurrent = mLink._mNext;
  1.1283 +#ifdef DEBUG
  1.1284 +      rv.mListLink = &mLink;
  1.1285 +#endif
  1.1286 +      return rv;
  1.1287 +    }
  1.1288 +
  1.1289 +    iterator begin()
  1.1290 +    {
  1.1291 +      iterator rv;
  1.1292 +      rv.mCurrent = mLink._mNext;
  1.1293 +#ifdef DEBUG
  1.1294 +      rv.mListLink = &mLink;
  1.1295 +#endif
  1.1296 +      return rv;
  1.1297 +    }
  1.1298 +
  1.1299 +    iterator begin(nsLineBox* aLine)
  1.1300 +    {
  1.1301 +      iterator rv;
  1.1302 +      rv.mCurrent = aLine;
  1.1303 +#ifdef DEBUG
  1.1304 +      rv.mListLink = &mLink;
  1.1305 +#endif
  1.1306 +      return rv;
  1.1307 +    }
  1.1308 +
  1.1309 +    const_iterator end() const
  1.1310 +    {
  1.1311 +      const_iterator rv;
  1.1312 +      rv.mCurrent = &mLink;
  1.1313 +#ifdef DEBUG
  1.1314 +      rv.mListLink = &mLink;
  1.1315 +#endif
  1.1316 +      return rv;
  1.1317 +    }
  1.1318 +
  1.1319 +    iterator end()
  1.1320 +    {
  1.1321 +      iterator rv;
  1.1322 +      rv.mCurrent = &mLink;
  1.1323 +#ifdef DEBUG
  1.1324 +      rv.mListLink = &mLink;
  1.1325 +#endif
  1.1326 +      return rv;
  1.1327 +    }
  1.1328 +
  1.1329 +    const_reverse_iterator rbegin() const
  1.1330 +    {
  1.1331 +      const_reverse_iterator rv;
  1.1332 +      rv.mCurrent = mLink._mPrev;
  1.1333 +#ifdef DEBUG
  1.1334 +      rv.mListLink = &mLink;
  1.1335 +#endif
  1.1336 +      return rv;
  1.1337 +    }
  1.1338 +
  1.1339 +    reverse_iterator rbegin()
  1.1340 +    {
  1.1341 +      reverse_iterator rv;
  1.1342 +      rv.mCurrent = mLink._mPrev;
  1.1343 +#ifdef DEBUG
  1.1344 +      rv.mListLink = &mLink;
  1.1345 +#endif
  1.1346 +      return rv;
  1.1347 +    }
  1.1348 +
  1.1349 +    reverse_iterator rbegin(nsLineBox* aLine)
  1.1350 +    {
  1.1351 +      reverse_iterator rv;
  1.1352 +      rv.mCurrent = aLine;
  1.1353 +#ifdef DEBUG
  1.1354 +      rv.mListLink = &mLink;
  1.1355 +#endif
  1.1356 +      return rv;
  1.1357 +    }
  1.1358 +
  1.1359 +    const_reverse_iterator rend() const
  1.1360 +    {
  1.1361 +      const_reverse_iterator rv;
  1.1362 +      rv.mCurrent = &mLink;
  1.1363 +#ifdef DEBUG
  1.1364 +      rv.mListLink = &mLink;
  1.1365 +#endif
  1.1366 +      return rv;
  1.1367 +    }
  1.1368 +
  1.1369 +    reverse_iterator rend()
  1.1370 +    {
  1.1371 +      reverse_iterator rv;
  1.1372 +      rv.mCurrent = &mLink;
  1.1373 +#ifdef DEBUG
  1.1374 +      rv.mListLink = &mLink;
  1.1375 +#endif
  1.1376 +      return rv;
  1.1377 +    }
  1.1378 +
  1.1379 +    bool empty() const
  1.1380 +    {
  1.1381 +      return mLink._mNext == &mLink;
  1.1382 +    }
  1.1383 +
  1.1384 +    // NOTE: O(N).
  1.1385 +    size_type size() const
  1.1386 +    {
  1.1387 +      size_type count = 0;
  1.1388 +      for (const link_type *cur = mLink._mNext;
  1.1389 +           cur != &mLink;
  1.1390 +           cur = cur->_mNext)
  1.1391 +      {
  1.1392 +        ++count;
  1.1393 +      }
  1.1394 +      return count;
  1.1395 +    }
  1.1396 +
  1.1397 +    pointer front()
  1.1398 +    {
  1.1399 +      NS_ASSERTION(!empty(), "no element to return");
  1.1400 +      return static_cast<pointer>(mLink._mNext);
  1.1401 +    }
  1.1402 +
  1.1403 +    const_pointer front() const
  1.1404 +    {
  1.1405 +      NS_ASSERTION(!empty(), "no element to return");
  1.1406 +      return static_cast<const_pointer>(mLink._mNext);
  1.1407 +    }
  1.1408 +
  1.1409 +    pointer back()
  1.1410 +    {
  1.1411 +      NS_ASSERTION(!empty(), "no element to return");
  1.1412 +      return static_cast<pointer>(mLink._mPrev);
  1.1413 +    }
  1.1414 +
  1.1415 +    const_pointer back() const
  1.1416 +    {
  1.1417 +      NS_ASSERTION(!empty(), "no element to return");
  1.1418 +      return static_cast<const_pointer>(mLink._mPrev);
  1.1419 +    }
  1.1420 +
  1.1421 +    void push_front(pointer aNew)
  1.1422 +    {
  1.1423 +      aNew->_mNext = mLink._mNext;
  1.1424 +      mLink._mNext->_mPrev = aNew;
  1.1425 +      aNew->_mPrev = &mLink;
  1.1426 +      mLink._mNext = aNew;
  1.1427 +    }
  1.1428 +
  1.1429 +    void pop_front()
  1.1430 +        // NOTE: leaves dangling next/prev pointers
  1.1431 +    {
  1.1432 +      NS_ASSERTION(!empty(), "no element to pop");
  1.1433 +      link_type *newFirst = mLink._mNext->_mNext;
  1.1434 +      newFirst->_mPrev = &mLink;
  1.1435 +      // mLink._mNext->_mNext = nullptr;
  1.1436 +      // mLink._mNext->_mPrev = nullptr;
  1.1437 +      mLink._mNext = newFirst;
  1.1438 +    }
  1.1439 +
  1.1440 +    void push_back(pointer aNew)
  1.1441 +    {
  1.1442 +      aNew->_mPrev = mLink._mPrev;
  1.1443 +      mLink._mPrev->_mNext = aNew;
  1.1444 +      aNew->_mNext = &mLink;
  1.1445 +      mLink._mPrev = aNew;
  1.1446 +    }
  1.1447 +
  1.1448 +    void pop_back()
  1.1449 +        // NOTE: leaves dangling next/prev pointers
  1.1450 +    {
  1.1451 +      NS_ASSERTION(!empty(), "no element to pop");
  1.1452 +      link_type *newLast = mLink._mPrev->_mPrev;
  1.1453 +      newLast->_mNext = &mLink;
  1.1454 +      // mLink._mPrev->_mPrev = nullptr;
  1.1455 +      // mLink._mPrev->_mNext = nullptr;
  1.1456 +      mLink._mPrev = newLast;
  1.1457 +    }
  1.1458 +
  1.1459 +    // inserts x before position
  1.1460 +    iterator before_insert(iterator position, pointer x)
  1.1461 +    {
  1.1462 +      // use |mCurrent| to prevent DEBUG_PASS_END assertions
  1.1463 +      x->_mPrev = position.mCurrent->_mPrev;
  1.1464 +      x->_mNext = position.mCurrent;
  1.1465 +      position.mCurrent->_mPrev->_mNext = x;
  1.1466 +      position.mCurrent->_mPrev = x;
  1.1467 +      return --position;
  1.1468 +    }
  1.1469 +
  1.1470 +    // inserts x after position
  1.1471 +    iterator after_insert(iterator position, pointer x)
  1.1472 +    {
  1.1473 +      // use |mCurrent| to prevent DEBUG_PASS_END assertions
  1.1474 +      x->_mNext = position.mCurrent->_mNext;
  1.1475 +      x->_mPrev = position.mCurrent;
  1.1476 +      position.mCurrent->_mNext->_mPrev = x;
  1.1477 +      position.mCurrent->_mNext = x;
  1.1478 +      return ++position;
  1.1479 +    }
  1.1480 +
  1.1481 +    // returns iterator pointing to after the element
  1.1482 +    iterator erase(iterator position)
  1.1483 +        // NOTE: leaves dangling next/prev pointers
  1.1484 +    {
  1.1485 +      position->_mPrev->_mNext = position->_mNext;
  1.1486 +      position->_mNext->_mPrev = position->_mPrev;
  1.1487 +      return ++position;
  1.1488 +    }
  1.1489 +
  1.1490 +    void swap(self_type& y)
  1.1491 +    {
  1.1492 +      link_type tmp(y.mLink);
  1.1493 +      y.mLink = mLink;
  1.1494 +      mLink = tmp;
  1.1495 +
  1.1496 +      if (!empty()) {
  1.1497 +        mLink._mNext->_mPrev = &mLink;
  1.1498 +        mLink._mPrev->_mNext = &mLink;
  1.1499 +      }
  1.1500 +
  1.1501 +      if (!y.empty()) {
  1.1502 +        y.mLink._mNext->_mPrev = &y.mLink;
  1.1503 +        y.mLink._mPrev->_mNext = &y.mLink;
  1.1504 +      }
  1.1505 +    }
  1.1506 +
  1.1507 +    void clear()
  1.1508 +        // NOTE:  leaves dangling next/prev pointers
  1.1509 +    {
  1.1510 +      mLink._mNext = &mLink;
  1.1511 +      mLink._mPrev = &mLink;
  1.1512 +    }
  1.1513 +
  1.1514 +    // inserts the conts of x before position and makes x empty
  1.1515 +    void splice(iterator position, self_type& x)
  1.1516 +    {
  1.1517 +      // use |mCurrent| to prevent DEBUG_PASS_END assertions
  1.1518 +      position.mCurrent->_mPrev->_mNext = x.mLink._mNext;
  1.1519 +      x.mLink._mNext->_mPrev = position.mCurrent->_mPrev;
  1.1520 +      x.mLink._mPrev->_mNext = position.mCurrent;
  1.1521 +      position.mCurrent->_mPrev = x.mLink._mPrev;
  1.1522 +      x.clear();
  1.1523 +    }
  1.1524 +
  1.1525 +    // Inserts element *i from list x before position and removes
  1.1526 +    // it from x.
  1.1527 +    void splice(iterator position, self_type& x, iterator i)
  1.1528 +    {
  1.1529 +      NS_ASSERTION(!x.empty(), "Can't insert from empty list.");
  1.1530 +      NS_ASSERTION(position != i && position.mCurrent != i->_mNext,
  1.1531 +                   "We don't check for this case.");
  1.1532 +
  1.1533 +      // remove from |x|
  1.1534 +      i->_mPrev->_mNext = i->_mNext;
  1.1535 +      i->_mNext->_mPrev = i->_mPrev;
  1.1536 +
  1.1537 +      // use |mCurrent| to prevent DEBUG_PASS_END assertions
  1.1538 +      // link into |this|, before-side
  1.1539 +      i->_mPrev = position.mCurrent->_mPrev;
  1.1540 +      position.mCurrent->_mPrev->_mNext = i.get();
  1.1541 +
  1.1542 +      // link into |this|, after-side
  1.1543 +      i->_mNext = position.mCurrent;
  1.1544 +      position.mCurrent->_mPrev = i.get();
  1.1545 +    }
  1.1546 +
  1.1547 +    // Inserts elements in [|first|, |last|), which are in |x|,
  1.1548 +    // into |this| before |position| and removes them from |x|.
  1.1549 +    void splice(iterator position, self_type& x, iterator first,
  1.1550 +                iterator last)
  1.1551 +    {
  1.1552 +      NS_ASSERTION(!x.empty(), "Can't insert from empty list.");
  1.1553 +
  1.1554 +      if (first == last)
  1.1555 +        return;
  1.1556 +
  1.1557 +      --last; // so we now want to move [first, last]
  1.1558 +      // remove from |x|
  1.1559 +      first->_mPrev->_mNext = last->_mNext;
  1.1560 +      last->_mNext->_mPrev = first->_mPrev;
  1.1561 +
  1.1562 +      // use |mCurrent| to prevent DEBUG_PASS_END assertions
  1.1563 +      // link into |this|, before-side
  1.1564 +      first->_mPrev = position.mCurrent->_mPrev;
  1.1565 +      position.mCurrent->_mPrev->_mNext = first.get();
  1.1566 +
  1.1567 +      // link into |this|, after-side
  1.1568 +      last->_mNext = position.mCurrent;
  1.1569 +      position.mCurrent->_mPrev = last.get();
  1.1570 +    }
  1.1571 +
  1.1572 +};
  1.1573 +
  1.1574 +
  1.1575 +// Many of these implementations of operator= don't work yet.  I don't
  1.1576 +// know why.
  1.1577 +
  1.1578 +#ifdef DEBUG
  1.1579 +
  1.1580 +  // NOTE: ASSIGN_FROM is meant to be used *only* as the entire body
  1.1581 +  // of a function and therefore lacks PR_{BEGIN,END}_MACRO
  1.1582 +#define ASSIGN_FROM(other_)          \
  1.1583 +  mCurrent = other_.mCurrent;        \
  1.1584 +  mListLink = other_.mListLink;      \
  1.1585 +  return *this;
  1.1586 +
  1.1587 +#else /* !NS_LINELIST_DEBUG_PASS_END */
  1.1588 +
  1.1589 +#define ASSIGN_FROM(other_)          \
  1.1590 +  mCurrent = other_.mCurrent;        \
  1.1591 +  return *this;
  1.1592 +
  1.1593 +#endif /* !NS_LINELIST_DEBUG_PASS_END */
  1.1594 +
  1.1595 +inline
  1.1596 +nsLineList_iterator&
  1.1597 +nsLineList_iterator::operator=(const nsLineList_iterator& aOther)
  1.1598 +{
  1.1599 +  ASSIGN_FROM(aOther)
  1.1600 +}
  1.1601 +
  1.1602 +inline
  1.1603 +nsLineList_iterator&
  1.1604 +nsLineList_iterator::operator=(const nsLineList_reverse_iterator& aOther)
  1.1605 +{
  1.1606 +  ASSIGN_FROM(aOther)
  1.1607 +}
  1.1608 +
  1.1609 +inline
  1.1610 +nsLineList_reverse_iterator&
  1.1611 +nsLineList_reverse_iterator::operator=(const nsLineList_iterator& aOther)
  1.1612 +{
  1.1613 +  ASSIGN_FROM(aOther)
  1.1614 +}
  1.1615 +
  1.1616 +inline
  1.1617 +nsLineList_reverse_iterator&
  1.1618 +nsLineList_reverse_iterator::operator=(const nsLineList_reverse_iterator& aOther)
  1.1619 +{
  1.1620 +  ASSIGN_FROM(aOther)
  1.1621 +}
  1.1622 +
  1.1623 +inline
  1.1624 +nsLineList_const_iterator&
  1.1625 +nsLineList_const_iterator::operator=(const nsLineList_iterator& aOther)
  1.1626 +{
  1.1627 +  ASSIGN_FROM(aOther)
  1.1628 +}
  1.1629 +
  1.1630 +inline
  1.1631 +nsLineList_const_iterator&
  1.1632 +nsLineList_const_iterator::operator=(const nsLineList_reverse_iterator& aOther)
  1.1633 +{
  1.1634 +  ASSIGN_FROM(aOther)
  1.1635 +}
  1.1636 +
  1.1637 +inline
  1.1638 +nsLineList_const_iterator&
  1.1639 +nsLineList_const_iterator::operator=(const nsLineList_const_iterator& aOther)
  1.1640 +{
  1.1641 +  ASSIGN_FROM(aOther)
  1.1642 +}
  1.1643 +
  1.1644 +inline
  1.1645 +nsLineList_const_iterator&
  1.1646 +nsLineList_const_iterator::operator=(const nsLineList_const_reverse_iterator& aOther)
  1.1647 +{
  1.1648 +  ASSIGN_FROM(aOther)
  1.1649 +}
  1.1650 +
  1.1651 +inline
  1.1652 +nsLineList_const_reverse_iterator&
  1.1653 +nsLineList_const_reverse_iterator::operator=(const nsLineList_iterator& aOther)
  1.1654 +{
  1.1655 +  ASSIGN_FROM(aOther)
  1.1656 +}
  1.1657 +
  1.1658 +inline
  1.1659 +nsLineList_const_reverse_iterator&
  1.1660 +nsLineList_const_reverse_iterator::operator=(const nsLineList_reverse_iterator& aOther)
  1.1661 +{
  1.1662 +  ASSIGN_FROM(aOther)
  1.1663 +}
  1.1664 +
  1.1665 +inline
  1.1666 +nsLineList_const_reverse_iterator&
  1.1667 +nsLineList_const_reverse_iterator::operator=(const nsLineList_const_iterator& aOther)
  1.1668 +{
  1.1669 +  ASSIGN_FROM(aOther)
  1.1670 +}
  1.1671 +
  1.1672 +inline
  1.1673 +nsLineList_const_reverse_iterator&
  1.1674 +nsLineList_const_reverse_iterator::operator=(const nsLineList_const_reverse_iterator& aOther)
  1.1675 +{
  1.1676 +  ASSIGN_FROM(aOther)
  1.1677 +}
  1.1678 +
  1.1679 +
  1.1680 +//----------------------------------------------------------------------
  1.1681 +
  1.1682 +class nsLineIterator MOZ_FINAL : public nsILineIterator
  1.1683 +{
  1.1684 +public:
  1.1685 +  nsLineIterator();
  1.1686 +  ~nsLineIterator();
  1.1687 +
  1.1688 +  virtual void DisposeLineIterator() MOZ_OVERRIDE;
  1.1689 +
  1.1690 +  virtual int32_t GetNumLines() MOZ_OVERRIDE;
  1.1691 +  virtual bool GetDirection() MOZ_OVERRIDE;
  1.1692 +  NS_IMETHOD GetLine(int32_t aLineNumber,
  1.1693 +                     nsIFrame** aFirstFrameOnLine,
  1.1694 +                     int32_t* aNumFramesOnLine,
  1.1695 +                     nsRect& aLineBounds,
  1.1696 +                     uint32_t* aLineFlags) MOZ_OVERRIDE;
  1.1697 +  virtual int32_t FindLineContaining(nsIFrame* aFrame, int32_t aStartLine = 0) MOZ_OVERRIDE;
  1.1698 +  NS_IMETHOD FindFrameAt(int32_t aLineNumber,
  1.1699 +                         nscoord aX,
  1.1700 +                         nsIFrame** aFrameFound,
  1.1701 +                         bool* aXIsBeforeFirstFrame,
  1.1702 +                         bool* aXIsAfterLastFrame) MOZ_OVERRIDE;
  1.1703 +
  1.1704 +  NS_IMETHOD GetNextSiblingOnLine(nsIFrame*& aFrame, int32_t aLineNumber) MOZ_OVERRIDE;
  1.1705 +  NS_IMETHOD CheckLineOrder(int32_t                  aLine,
  1.1706 +                            bool                     *aIsReordered,
  1.1707 +                            nsIFrame                 **aFirstVisual,
  1.1708 +                            nsIFrame                 **aLastVisual) MOZ_OVERRIDE;
  1.1709 +  nsresult Init(nsLineList& aLines, bool aRightToLeft);
  1.1710 +
  1.1711 +private:
  1.1712 +  nsLineBox* PrevLine() {
  1.1713 +    if (0 == mIndex) {
  1.1714 +      return nullptr;
  1.1715 +    }
  1.1716 +    return mLines[--mIndex];
  1.1717 +  }
  1.1718 +
  1.1719 +  nsLineBox* NextLine() {
  1.1720 +    if (mIndex >= mNumLines - 1) {
  1.1721 +      return nullptr;
  1.1722 +    }
  1.1723 +    return mLines[++mIndex];
  1.1724 +  }
  1.1725 +
  1.1726 +  nsLineBox* LineAt(int32_t aIndex) {
  1.1727 +    if ((aIndex < 0) || (aIndex >= mNumLines)) {
  1.1728 +      return nullptr;
  1.1729 +    }
  1.1730 +    return mLines[aIndex];
  1.1731 +  }
  1.1732 +
  1.1733 +  nsLineBox** mLines;
  1.1734 +  int32_t mIndex;
  1.1735 +  int32_t mNumLines;
  1.1736 +  bool mRightToLeft;
  1.1737 +};
  1.1738 +
  1.1739 +#endif /* nsLineBox_h___ */

mercurial