layout/generic/nsLineLayout.h

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/layout/generic/nsLineLayout.h	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,579 @@
     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 + *
     1.7 + * This Source Code Form is subject to the terms of the Mozilla Public
     1.8 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.9 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
    1.10 + * This Original Code has been modified by IBM Corporation. Modifications made by IBM 
    1.11 + * described herein are Copyright (c) International Business Machines Corporation, 2000.
    1.12 + * Modifications to Mozilla code or documentation identified per MPL Section 3.3
    1.13 + *
    1.14 + * Date             Modified by     Description of modification
    1.15 + * 04/20/2000       IBM Corp.      OS/2 VisualAge build.
    1.16 + */
    1.17 +
    1.18 +/* state and methods used while laying out a single line of a block frame */
    1.19 +
    1.20 +#ifndef nsLineLayout_h___
    1.21 +#define nsLineLayout_h___
    1.22 +
    1.23 +#include "nsLineBox.h"
    1.24 +#include "nsBlockReflowState.h"
    1.25 +#include "plarena.h"
    1.26 +#include "gfxTypes.h"
    1.27 +#include "WritingModes.h"
    1.28 +
    1.29 +class nsFloatManager;
    1.30 +struct nsStyleText;
    1.31 +
    1.32 +class nsLineLayout {
    1.33 +public:
    1.34 +  nsLineLayout(nsPresContext* aPresContext,
    1.35 +               nsFloatManager* aFloatManager,
    1.36 +               const nsHTMLReflowState* aOuterReflowState,
    1.37 +               const nsLineList::iterator* aLine);
    1.38 +  ~nsLineLayout();
    1.39 +
    1.40 +  void Init(nsBlockReflowState* aState, nscoord aMinLineBSize,
    1.41 +            int32_t aLineNumber) {
    1.42 +    mBlockRS = aState;
    1.43 +    mMinLineBSize = aMinLineBSize;
    1.44 +    mLineNumber = aLineNumber;
    1.45 +  }
    1.46 +
    1.47 +  int32_t GetLineNumber() const {
    1.48 +    return mLineNumber;
    1.49 +  }
    1.50 +
    1.51 +  void BeginLineReflow(nscoord aICoord, nscoord aBCoord,
    1.52 +                       nscoord aISize, nscoord aBSize,
    1.53 +                       bool aImpactedByFloats,
    1.54 +                       bool aIsTopOfPage,
    1.55 +                       mozilla::WritingMode aWritingMode,
    1.56 +                       nscoord aContainerWidth);
    1.57 +
    1.58 +  void EndLineReflow();
    1.59 +
    1.60 +  /**
    1.61 +   * Called when a float has been placed. This method updates the
    1.62 +   * inline frame and span data to account for any change in positions
    1.63 +   * due to available space for the line boxes changing.
    1.64 +   * @param aX/aY/aWidth/aHeight are the new available
    1.65 +   * space rectangle, relative to the containing block.
    1.66 +   * @param aFloatFrame the float frame that was placed.
    1.67 +   */
    1.68 +  void UpdateBand(const nsRect& aNewAvailableSpace,
    1.69 +                  nsIFrame* aFloatFrame);
    1.70 +
    1.71 +  void BeginSpan(nsIFrame* aFrame, const nsHTMLReflowState* aSpanReflowState,
    1.72 +                 nscoord aLeftEdge, nscoord aRightEdge, nscoord* aBaseline);
    1.73 +
    1.74 +  // Returns the width of the span
    1.75 +  nscoord EndSpan(nsIFrame* aFrame);
    1.76 +
    1.77 +  int32_t GetCurrentSpanCount() const;
    1.78 +
    1.79 +  void SplitLineTo(int32_t aNewCount);
    1.80 +
    1.81 +  bool IsZeroBSize();
    1.82 +
    1.83 +  // Reflows the frame and returns the reflow status. aPushedFrame is true
    1.84 +  // if the frame is pushed to the next line because it doesn't fit
    1.85 +  nsresult ReflowFrame(nsIFrame* aFrame,
    1.86 +                       nsReflowStatus& aReflowStatus,
    1.87 +                       nsHTMLReflowMetrics* aMetrics,
    1.88 +                       bool& aPushedFrame);
    1.89 +
    1.90 +  void AddBulletFrame(nsIFrame* aFrame, const nsHTMLReflowMetrics& aMetrics);
    1.91 +
    1.92 +  void RemoveBulletFrame(nsIFrame* aFrame) {
    1.93 +    PushFrame(aFrame);
    1.94 +  }
    1.95 +
    1.96 +  void BlockDirAlignLine();
    1.97 +
    1.98 +  bool TrimTrailingWhiteSpace();
    1.99 +
   1.100 +  void InlineDirAlignFrames(nsLineBox* aLine, bool aIsLastLine);
   1.101 +
   1.102 +  /**
   1.103 +   * Handle all the relative positioning in the line, compute the
   1.104 +   * combined area (== overflow area) for the line, and handle view
   1.105 +   * sizing/positioning and the setting of the overflow rect.
   1.106 +   */
   1.107 +  void RelativePositionFrames(nsOverflowAreas& aOverflowAreas);
   1.108 +
   1.109 +  // Support methods for word-wrapping during line reflow
   1.110 +
   1.111 +  void SetTextJustificationWeights(int32_t aNumSpaces, int32_t aNumLetters) {
   1.112 +    mTextJustificationNumSpaces = aNumSpaces;
   1.113 +    mTextJustificationNumLetters = aNumLetters;
   1.114 +  }
   1.115 +
   1.116 +  /**
   1.117 +   * @return true if so far during reflow no non-empty content has been
   1.118 +   * placed in the line (according to nsIFrame::IsEmpty())
   1.119 +   */
   1.120 +  bool LineIsEmpty() const
   1.121 +  {
   1.122 +    return mLineIsEmpty;
   1.123 +  }
   1.124 +
   1.125 +  /**
   1.126 +   * @return true if so far during reflow no non-empty leaf content
   1.127 +   * (non-collapsed whitespace, replaced element, inline-block, etc) has been
   1.128 +   * placed in the line
   1.129 +   */
   1.130 +  bool LineAtStart() const
   1.131 +  {
   1.132 +    return mLineAtStart;
   1.133 +  }
   1.134 +
   1.135 +  bool LineIsBreakable() const;
   1.136 +
   1.137 +  bool GetLineEndsInBR() const 
   1.138 +  { 
   1.139 +    return mLineEndsInBR;
   1.140 +  }
   1.141 +
   1.142 +  void SetLineEndsInBR(bool aOn) 
   1.143 +  { 
   1.144 +    mLineEndsInBR = aOn;
   1.145 +  }
   1.146 +
   1.147 +  //----------------------------------------
   1.148 +  // Inform the line-layout about the presence of a floating frame
   1.149 +  // XXX get rid of this: use get-frame-type?
   1.150 +  bool AddFloat(nsIFrame* aFloat, nscoord aAvailableWidth)
   1.151 +  {
   1.152 +    return mBlockRS->AddFloat(this, aFloat, aAvailableWidth);
   1.153 +  }
   1.154 +
   1.155 +  void SetTrimmableWidth(nscoord aTrimmableWidth) {
   1.156 +    mTrimmableWidth = aTrimmableWidth;
   1.157 +  }
   1.158 +
   1.159 +  //----------------------------------------
   1.160 +
   1.161 +  bool GetFirstLetterStyleOK() const {
   1.162 +    return mFirstLetterStyleOK;
   1.163 +  }
   1.164 +
   1.165 +  void SetFirstLetterStyleOK(bool aSetting) {
   1.166 +    mFirstLetterStyleOK = aSetting;
   1.167 +  }
   1.168 +
   1.169 +  bool GetInFirstLetter() const {
   1.170 +    return mInFirstLetter;
   1.171 +  }
   1.172 +
   1.173 +  void SetInFirstLetter(bool aSetting) {
   1.174 +    mInFirstLetter = aSetting;
   1.175 +  }
   1.176 +
   1.177 +  bool GetInFirstLine() const {
   1.178 +    return mInFirstLine;
   1.179 +  }
   1.180 +
   1.181 +  void SetInFirstLine(bool aSetting) {
   1.182 +    mInFirstLine = aSetting;
   1.183 +  }
   1.184 +
   1.185 +  // Calling this during block reflow ensures that the next line of inlines
   1.186 +  // will be marked dirty, if there is one.
   1.187 +  void SetDirtyNextLine() {
   1.188 +    mDirtyNextLine = true;
   1.189 +  }
   1.190 +  bool GetDirtyNextLine() {
   1.191 +    return mDirtyNextLine;
   1.192 +  }
   1.193 +
   1.194 +  //----------------------------------------
   1.195 +
   1.196 +  nsPresContext* mPresContext;
   1.197 +
   1.198 +  /**
   1.199 +   * Record where an optional break could have been placed. During line reflow,
   1.200 +   * frames containing optional break points (e.g., whitespace in text frames)
   1.201 +   * can call SetLastOptionalBreakPosition to record where a break could
   1.202 +   * have been made, but wasn't because we decided to place more content on
   1.203 +   * the line. For non-text frames, offset 0 means
   1.204 +   * before the content, offset INT32_MAX means after the content.
   1.205 +   * 
   1.206 +   * Currently this is used to handle cases where a single word comprises
   1.207 +   * multiple frames, and the first frame fits on the line but the whole word
   1.208 +   * doesn't. We look back to the last optional break position and
   1.209 +   * reflow the whole line again, forcing a break at that position. The last
   1.210 +   * optional break position could be in a text frame or else after a frame
   1.211 +   * that cannot be part of a text run, so those are the positions we record.
   1.212 +   * 
   1.213 +   * @param aFits set to true if the break position is within the available width.
   1.214 +   * 
   1.215 +   * @param aPriority the priority of the break opportunity. If we are
   1.216 +   * prioritizing break opportunities, we will not set a break if we have
   1.217 +   * already set a break with a higher priority. @see gfxBreakPriority.
   1.218 +   *
   1.219 +   * @return true if we are actually reflowing with forced break position and we
   1.220 +   * should break here
   1.221 +   */
   1.222 +  bool NotifyOptionalBreakPosition(nsIContent* aContent, int32_t aOffset,
   1.223 +                                     bool aFits, gfxBreakPriority aPriority) {
   1.224 +    NS_ASSERTION(!aFits || !mNeedBackup,
   1.225 +                  "Shouldn't be updating the break position with a break that fits after we've already flagged an overrun");
   1.226 +    // Remember the last break position that fits; if there was no break that fit,
   1.227 +    // just remember the first break
   1.228 +    if ((aFits && aPriority >= mLastOptionalBreakPriority) ||
   1.229 +        !mLastOptionalBreakContent) {
   1.230 +      mLastOptionalBreakContent = aContent;
   1.231 +      mLastOptionalBreakContentOffset = aOffset;
   1.232 +      mLastOptionalBreakPriority = aPriority;
   1.233 +    }
   1.234 +    return aContent && mForceBreakContent == aContent &&
   1.235 +      mForceBreakContentOffset == aOffset;
   1.236 +  }
   1.237 +  /**
   1.238 +   * Like NotifyOptionalBreakPosition, but here it's OK for mNeedBackup
   1.239 +   * to be set, because the caller is merely pruning some saved break position(s)
   1.240 +   * that are actually not feasible.
   1.241 +   */
   1.242 +  void RestoreSavedBreakPosition(nsIContent* aContent, int32_t aOffset,
   1.243 +                                 gfxBreakPriority aPriority) {
   1.244 +    mLastOptionalBreakContent = aContent;
   1.245 +    mLastOptionalBreakContentOffset = aOffset;
   1.246 +    mLastOptionalBreakPriority = aPriority;
   1.247 +  }
   1.248 +  /**
   1.249 +   * Signal that no backing up will be required after all.
   1.250 +   */
   1.251 +  void ClearOptionalBreakPosition() {
   1.252 +    mNeedBackup = false;
   1.253 +    mLastOptionalBreakContent = nullptr;
   1.254 +    mLastOptionalBreakContentOffset = -1;
   1.255 +    mLastOptionalBreakPriority = gfxBreakPriority::eNoBreak;
   1.256 +  }
   1.257 +  // Retrieve last set optional break position. When this returns null, no
   1.258 +  // optional break has been recorded (which means that the line can't break yet).
   1.259 +  nsIContent* GetLastOptionalBreakPosition(int32_t* aOffset,
   1.260 +                                           gfxBreakPriority* aPriority) {
   1.261 +    *aOffset = mLastOptionalBreakContentOffset;
   1.262 +    *aPriority = mLastOptionalBreakPriority;
   1.263 +    return mLastOptionalBreakContent;
   1.264 +  }
   1.265 +  
   1.266 +  /**
   1.267 +   * Check whether frames overflowed the available width and CanPlaceFrame
   1.268 +   * requested backing up to a saved break position.
   1.269 +   */  
   1.270 +  bool NeedsBackup() { return mNeedBackup; }
   1.271 +  
   1.272 +  // Line layout may place too much content on a line, overflowing its available
   1.273 +  // width. When that happens, if SetLastOptionalBreakPosition has been
   1.274 +  // used to record an optional break that wasn't taken, we can reflow the line
   1.275 +  // again and force the break to happen at that point (i.e., backtracking
   1.276 +  // to the last choice point).
   1.277 +
   1.278 +  // Record that we want to break at the given content+offset (which
   1.279 +  // should have been previously returned by GetLastOptionalBreakPosition
   1.280 +  // from another nsLineLayout).
   1.281 +  void ForceBreakAtPosition(nsIContent* aContent, int32_t aOffset) {
   1.282 +    mForceBreakContent = aContent;
   1.283 +    mForceBreakContentOffset = aOffset;
   1.284 +  }
   1.285 +  bool HaveForcedBreakPosition() { return mForceBreakContent != nullptr; }
   1.286 +  int32_t GetForcedBreakPosition(nsIContent* aContent) {
   1.287 +    return mForceBreakContent == aContent ? mForceBreakContentOffset : -1;
   1.288 +  }
   1.289 +
   1.290 +  /**
   1.291 +   * This can't be null. It usually returns a block frame but may return
   1.292 +   * some other kind of frame when inline frames are reflowed in a non-block
   1.293 +   * context (e.g. MathML or floating first-letter).
   1.294 +   */
   1.295 +  nsIFrame* LineContainerFrame() const { return mBlockReflowState->frame; }
   1.296 +  const nsHTMLReflowState* LineContainerRS() const { return mBlockReflowState; }
   1.297 +  const nsLineList::iterator* GetLine() const {
   1.298 +    return mGotLineBox ? &mLineBox : nullptr;
   1.299 +  }
   1.300 +  nsLineList::iterator* GetLine() {
   1.301 +    return mGotLineBox ? &mLineBox : nullptr;
   1.302 +  }
   1.303 +  
   1.304 +  /**
   1.305 +   * Returns the accumulated advance width of frames before the current frame
   1.306 +   * on the line, plus the line container's left border+padding.
   1.307 +   * This is always positive, the advance width is measured from
   1.308 +   * the right edge for RTL blocks and from the left edge for LTR blocks.
   1.309 +   * In other words, the current frame's distance from the line container's
   1.310 +   * start content edge is:
   1.311 +   * <code>GetCurrentFrameInlineDistanceFromBlock() - lineContainer->GetUsedBorderAndPadding().left</code>
   1.312 +   * Note the use of <code>.left</code> for both LTR and RTL line containers.
   1.313 +   */
   1.314 +  nscoord GetCurrentFrameInlineDistanceFromBlock();
   1.315 +
   1.316 +protected:
   1.317 +  // This state is constant for a given block frame doing line layout
   1.318 +  nsFloatManager* mFloatManager;
   1.319 +  const nsStyleText* mStyleText; // for the block
   1.320 +  const nsHTMLReflowState* mBlockReflowState;
   1.321 +
   1.322 +  nsIContent* mLastOptionalBreakContent;
   1.323 +  nsIContent* mForceBreakContent;
   1.324 +  
   1.325 +  // XXX remove this when landing bug 154892 (splitting absolute positioned frames)
   1.326 +  friend class nsInlineFrame;
   1.327 +
   1.328 +  nsBlockReflowState* mBlockRS;/* XXX hack! */
   1.329 +
   1.330 +  nsLineList::iterator mLineBox;
   1.331 +
   1.332 +  // Per-frame data recorded by the line-layout reflow logic. This
   1.333 +  // state is the state needed to post-process the line after reflow
   1.334 +  // has completed (block-direction alignment, inline-direction alignment,
   1.335 +  // justification and relative positioning).
   1.336 +
   1.337 +  struct PerSpanData;
   1.338 +  struct PerFrameData;
   1.339 +  friend struct PerSpanData;
   1.340 +  friend struct PerFrameData;
   1.341 +  struct PerFrameData
   1.342 +  {
   1.343 +    PerFrameData(mozilla::WritingMode aWritingMode)
   1.344 +      : mBounds(aWritingMode)
   1.345 +      , mMargin(aWritingMode)
   1.346 +      , mBorderPadding(aWritingMode)
   1.347 +      , mOffsets(aWritingMode)
   1.348 +    {}
   1.349 +
   1.350 +    // link to next/prev frame in same span
   1.351 +    PerFrameData* mNext;
   1.352 +    PerFrameData* mPrev;
   1.353 +
   1.354 +    // pointer to child span data if this is an inline container frame
   1.355 +    PerSpanData* mSpan;
   1.356 +
   1.357 +    // The frame
   1.358 +    nsIFrame* mFrame;
   1.359 +
   1.360 +    // From metrics
   1.361 +    nscoord mAscent;
   1.362 +    // note that mBounds is a logical rect in the *line*'s writing mode.
   1.363 +    // When setting frame coordinates, we have to convert to the frame's
   1.364 +    //  writing mode
   1.365 +    mozilla::LogicalRect mBounds;
   1.366 +    nsOverflowAreas mOverflowAreas;
   1.367 +
   1.368 +    // From reflow-state
   1.369 +    mozilla::LogicalMargin mMargin;
   1.370 +    mozilla::LogicalMargin mBorderPadding;
   1.371 +    mozilla::LogicalMargin mOffsets;
   1.372 +
   1.373 +    // state for text justification
   1.374 +    int32_t mJustificationNumSpaces;
   1.375 +    int32_t mJustificationNumLetters;
   1.376 +    
   1.377 +    // Other state we use
   1.378 +    uint8_t mBlockDirAlign;
   1.379 +
   1.380 +// PerFrameData flags
   1.381 +#define PFD_RELATIVEPOS                 0x00000001
   1.382 +#define PFD_ISTEXTFRAME                 0x00000002
   1.383 +#define PFD_ISNONEMPTYTEXTFRAME         0x00000004
   1.384 +#define PFD_ISNONWHITESPACETEXTFRAME    0x00000008
   1.385 +#define PFD_ISLETTERFRAME               0x00000010
   1.386 +#define PFD_RECOMPUTEOVERFLOW           0x00000020
   1.387 +#define PFD_ISBULLET                    0x00000040
   1.388 +#define PFD_SKIPWHENTRIMMINGWHITESPACE  0x00000080
   1.389 +#define PFD_LASTFLAG                    PFD_SKIPWHENTRIMMINGWHITESPACE
   1.390 +
   1.391 +    uint8_t mFlags;
   1.392 +
   1.393 +    void SetFlag(uint32_t aFlag, bool aValue)
   1.394 +    {
   1.395 +      NS_ASSERTION(aFlag<=PFD_LASTFLAG, "bad flag");
   1.396 +      NS_ASSERTION(aFlag<=UINT8_MAX, "bad flag");
   1.397 +      if (aValue) { // set flag
   1.398 +        mFlags |= aFlag;
   1.399 +      }
   1.400 +      else {        // unset flag
   1.401 +        mFlags &= ~aFlag;
   1.402 +      }
   1.403 +    }
   1.404 +
   1.405 +    bool GetFlag(uint32_t aFlag) const
   1.406 +    {
   1.407 +      NS_ASSERTION(aFlag<=PFD_LASTFLAG, "bad flag");
   1.408 +      return !!(mFlags & aFlag);
   1.409 +    }
   1.410 +
   1.411 +
   1.412 +    PerFrameData* Last() {
   1.413 +      PerFrameData* pfd = this;
   1.414 +      while (pfd->mNext) {
   1.415 +        pfd = pfd->mNext;
   1.416 +      }
   1.417 +      return pfd;
   1.418 +    }
   1.419 +  };
   1.420 +  PerFrameData* mFrameFreeList;
   1.421 +
   1.422 +  struct PerSpanData {
   1.423 +    union {
   1.424 +      PerSpanData* mParent;
   1.425 +      PerSpanData* mNextFreeSpan;
   1.426 +    };
   1.427 +    PerFrameData* mFrame;
   1.428 +    PerFrameData* mFirstFrame;
   1.429 +    PerFrameData* mLastFrame;
   1.430 +
   1.431 +    const nsHTMLReflowState* mReflowState;
   1.432 +    bool mNoWrap;
   1.433 +    mozilla::WritingMode mWritingMode;
   1.434 +    bool mZeroEffectiveSpanBox;
   1.435 +    bool mContainsFloat;
   1.436 +    bool mHasNonemptyContent;
   1.437 +
   1.438 +    nscoord mIStart;
   1.439 +    nscoord mICoord;
   1.440 +    nscoord mIEnd;
   1.441 +
   1.442 +    nscoord mBStartLeading, mBEndLeading;
   1.443 +    nscoord mLogicalBSize;
   1.444 +    nscoord mMinBCoord, mMaxBCoord;
   1.445 +    nscoord* mBaseline;
   1.446 +
   1.447 +    void AppendFrame(PerFrameData* pfd) {
   1.448 +      if (nullptr == mLastFrame) {
   1.449 +        mFirstFrame = pfd;
   1.450 +      }
   1.451 +      else {
   1.452 +        mLastFrame->mNext = pfd;
   1.453 +        pfd->mPrev = mLastFrame;
   1.454 +      }
   1.455 +      mLastFrame = pfd;
   1.456 +    }
   1.457 +  };
   1.458 +  PerSpanData* mSpanFreeList;
   1.459 +  PerSpanData* mRootSpan;
   1.460 +  PerSpanData* mCurrentSpan;
   1.461 +
   1.462 +  gfxBreakPriority mLastOptionalBreakPriority;
   1.463 +  int32_t     mLastOptionalBreakContentOffset;
   1.464 +  int32_t     mForceBreakContentOffset;
   1.465 +
   1.466 +  nscoord mMinLineBSize;
   1.467 +  
   1.468 +  // The amount of text indent that we applied to this line, needed for
   1.469 +  // max-element-size calculation.
   1.470 +  nscoord mTextIndent;
   1.471 +
   1.472 +  // This state varies during the reflow of a line but is line
   1.473 +  // "global" state not span "local" state.
   1.474 +  int32_t mLineNumber;
   1.475 +  int32_t mTextJustificationNumSpaces;
   1.476 +  int32_t mTextJustificationNumLetters;
   1.477 +
   1.478 +  int32_t mTotalPlacedFrames;
   1.479 +
   1.480 +  nscoord mBStartEdge;
   1.481 +  nscoord mMaxStartBoxBSize;
   1.482 +  nscoord mMaxEndBoxBSize;
   1.483 +
   1.484 +  nscoord mInflationMinFontSize;
   1.485 +
   1.486 +  // Final computed line-bSize value after BlockDirAlignFrames for
   1.487 +  // the block has been called.
   1.488 +  nscoord mFinalLineBSize;
   1.489 +  
   1.490 +  // Amount of trimmable whitespace width for the trailing text frame, if any
   1.491 +  nscoord mTrimmableWidth;
   1.492 +
   1.493 +  nscoord mContainerWidth;
   1.494 +
   1.495 +  bool mFirstLetterStyleOK      : 1;
   1.496 +  bool mIsTopOfPage             : 1;
   1.497 +  bool mImpactedByFloats        : 1;
   1.498 +  bool mLastFloatWasLetterFrame : 1;
   1.499 +  bool mLineIsEmpty             : 1;
   1.500 +  bool mLineEndsInBR            : 1;
   1.501 +  bool mNeedBackup              : 1;
   1.502 +  bool mInFirstLine             : 1;
   1.503 +  bool mGotLineBox              : 1;
   1.504 +  bool mInFirstLetter           : 1;
   1.505 +  bool mHasBullet               : 1;
   1.506 +  bool mDirtyNextLine           : 1;
   1.507 +  bool mLineAtStart             : 1;
   1.508 +
   1.509 +  int32_t mSpanDepth;
   1.510 +#ifdef DEBUG
   1.511 +  int32_t mSpansAllocated, mSpansFreed;
   1.512 +  int32_t mFramesAllocated, mFramesFreed;
   1.513 +#endif
   1.514 +  PLArenaPool mArena; // Per span and per frame data, 4 byte aligned
   1.515 +
   1.516 +  /**
   1.517 +   * Allocate a PerFrameData from the mArena pool. The allocation is infallible.
   1.518 +   */
   1.519 +  PerFrameData* NewPerFrameData(nsIFrame* aFrame);
   1.520 +
   1.521 +  /**
   1.522 +   * Allocate a PerSpanData from the mArena pool. The allocation is infallible.
   1.523 +   */
   1.524 +  PerSpanData* NewPerSpanData();
   1.525 +
   1.526 +  void FreeSpan(PerSpanData* psd);
   1.527 +
   1.528 +  bool InBlockContext() const {
   1.529 +    return mSpanDepth == 0;
   1.530 +  }
   1.531 +
   1.532 +  void PushFrame(nsIFrame* aFrame);
   1.533 +
   1.534 +  void AllowForStartMargin(PerFrameData* pfd,
   1.535 +                           nsHTMLReflowState& aReflowState);
   1.536 +
   1.537 +  bool CanPlaceFrame(PerFrameData* pfd,
   1.538 +                       bool aNotSafeToBreak,
   1.539 +                       bool aFrameCanContinueTextRun,
   1.540 +                       bool aCanRollBackBeforeFrame,
   1.541 +                       nsHTMLReflowMetrics& aMetrics,
   1.542 +                       nsReflowStatus& aStatus,
   1.543 +                       bool* aOptionalBreakAfterFits);
   1.544 +
   1.545 +  void PlaceFrame(PerFrameData* pfd,
   1.546 +                  nsHTMLReflowMetrics& aMetrics);
   1.547 +
   1.548 +  void BlockDirAlignFrames(PerSpanData* psd);
   1.549 +
   1.550 +  void PlaceStartEndFrames(PerSpanData* psd,
   1.551 +                           nscoord aDistanceFromStart,
   1.552 +                           nscoord aLineBSize);
   1.553 +
   1.554 +  void RelativePositionFrames(PerSpanData* psd, nsOverflowAreas& aOverflowAreas);
   1.555 +
   1.556 +  bool TrimTrailingWhiteSpaceIn(PerSpanData* psd, nscoord* aDeltaISize);
   1.557 +
   1.558 +  void ComputeJustificationWeights(PerSpanData* psd, int32_t* numSpaces, int32_t* numLetters);
   1.559 +
   1.560 +  struct FrameJustificationState {
   1.561 +    int32_t mTotalNumSpaces;
   1.562 +    int32_t mTotalNumLetters;
   1.563 +    nscoord mTotalWidthForSpaces;
   1.564 +    nscoord mTotalWidthForLetters;
   1.565 +    int32_t mNumSpacesProcessed;
   1.566 +    int32_t mNumLettersProcessed;
   1.567 +    nscoord mWidthForSpacesProcessed;
   1.568 +    nscoord mWidthForLettersProcessed;
   1.569 +  };
   1.570 +
   1.571 +  // Apply justification.  The return value is the amount by which the width of
   1.572 +  // the span corresponding to aPSD got increased due to justification.
   1.573 +  nscoord ApplyFrameJustification(PerSpanData* aPSD,
   1.574 +                                  FrameJustificationState* aState);
   1.575 +
   1.576 +
   1.577 +#ifdef DEBUG
   1.578 +  void DumpPerSpanData(PerSpanData* psd, int32_t aIndent);
   1.579 +#endif
   1.580 +};
   1.581 +
   1.582 +#endif /* nsLineLayout_h___ */

mercurial