LCOV - code coverage report
Current view: top level - layout/generic - nsLineLayout.h (source / functions) Hit Total Coverage
Test: output.info Lines: 73 124 58.9 %
Date: 2017-07-14 16:53:18 Functions: 25 44 56.8 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
       2             :  * vim:cindent:ts=2:et:sw=2:
       3             :  *
       4             :  * This Source Code Form is subject to the terms of the Mozilla Public
       5             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       6             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       7             :  * This Original Code has been modified by IBM Corporation. Modifications made by IBM
       8             :  * described herein are Copyright (c) International Business Machines Corporation, 2000.
       9             :  * Modifications to Mozilla code or documentation identified per MPL Section 3.3
      10             :  *
      11             :  * Date             Modified by     Description of modification
      12             :  * 04/20/2000       IBM Corp.      OS/2 VisualAge build.
      13             :  */
      14             : 
      15             : /* state and methods used while laying out a single line of a block frame */
      16             : 
      17             : #ifndef nsLineLayout_h___
      18             : #define nsLineLayout_h___
      19             : 
      20             : #include "gfxTypes.h"
      21             : #include "JustificationUtils.h"
      22             : #include "mozilla/ArenaAllocator.h"
      23             : #include "mozilla/WritingModes.h"
      24             : #include "BlockReflowInput.h"
      25             : #include "nsLineBox.h"
      26             : 
      27             : class nsFloatManager;
      28             : struct nsStyleText;
      29             : 
      30             : class nsLineLayout {
      31             :   using BlockReflowInput = mozilla::BlockReflowInput;
      32             :   using ReflowInput = mozilla::ReflowInput;
      33             :   using ReflowOutput = mozilla::ReflowOutput;
      34             : 
      35             : public:
      36             :   /**
      37             :    * @param aBaseLineLayout the nsLineLayout for ruby base,
      38             :    * nullptr if no separate base nsLineLayout is needed.
      39             :    */
      40             :   nsLineLayout(nsPresContext* aPresContext,
      41             :                nsFloatManager* aFloatManager,
      42             :                const ReflowInput* aOuterReflowInput,
      43             :                const nsLineList::iterator* aLine,
      44             :                nsLineLayout* aBaseLineLayout);
      45             :   ~nsLineLayout();
      46             : 
      47          75 :   void Init(BlockReflowInput* aState, nscoord aMinLineBSize,
      48             :             int32_t aLineNumber) {
      49          75 :     mBlockRI = aState;
      50          75 :     mMinLineBSize = aMinLineBSize;
      51          75 :     mLineNumber = aLineNumber;
      52          75 :   }
      53             : 
      54          75 :   int32_t GetLineNumber() const {
      55          75 :     return mLineNumber;
      56             :   }
      57             : 
      58             :   void BeginLineReflow(nscoord aICoord, nscoord aBCoord,
      59             :                        nscoord aISize, nscoord aBSize,
      60             :                        bool aImpactedByFloats,
      61             :                        bool aIsTopOfPage,
      62             :                        mozilla::WritingMode aWritingMode,
      63             :                        const nsSize& aContainerSize);
      64             : 
      65             :   void EndLineReflow();
      66             : 
      67             :   /**
      68             :    * Called when a float has been placed. This method updates the
      69             :    * inline frame and span data to account for any change in positions
      70             :    * due to available space for the line boxes changing.
      71             :    * @param aX/aY/aWidth/aHeight are the new available
      72             :    * space rectangle, relative to the containing block.
      73             :    * @param aFloatFrame the float frame that was placed.
      74             :    */
      75             :   void UpdateBand(mozilla::WritingMode aWM,
      76             :                   const mozilla::LogicalRect& aNewAvailableSpace,
      77             :                   nsIFrame* aFloatFrame);
      78             : 
      79             :   void BeginSpan(nsIFrame* aFrame, const ReflowInput* aSpanReflowInput,
      80             :                  nscoord aLeftEdge, nscoord aRightEdge, nscoord* aBaseline);
      81             : 
      82             :   // Returns the width of the span
      83             :   nscoord EndSpan(nsIFrame* aFrame);
      84             : 
      85             :   // This method attaches the last frame reflowed in this line layout
      86             :   // to that in the base line layout.
      87           0 :   void AttachLastFrameToBaseLineLayout()
      88             :   {
      89           0 :     AttachFrameToBaseLineLayout(LastFrame());
      90           0 :   }
      91             : 
      92             :   // This method attaches the root frame of this line layout to the
      93             :   // last reflowed frame in the base line layout.
      94           0 :   void AttachRootFrameToBaseLineLayout()
      95             :   {
      96           0 :     AttachFrameToBaseLineLayout(mRootSpan->mFrame);
      97           0 :   }
      98             : 
      99             :   int32_t GetCurrentSpanCount() const;
     100             : 
     101             :   void SplitLineTo(int32_t aNewCount);
     102             : 
     103             :   bool IsZeroBSize();
     104             : 
     105             :   // Reflows the frame and returns the reflow status. aPushedFrame is true
     106             :   // if the frame is pushed to the next line because it doesn't fit.
     107             :   void ReflowFrame(nsIFrame* aFrame,
     108             :                    nsReflowStatus& aReflowStatus,
     109             :                    ReflowOutput* aMetrics,
     110             :                    bool& aPushedFrame);
     111             : 
     112             :   void AddBulletFrame(nsIFrame* aFrame, const ReflowOutput& aMetrics);
     113             : 
     114           0 :   void RemoveBulletFrame(nsIFrame* aFrame) {
     115           0 :     PushFrame(aFrame);
     116           0 :   }
     117             : 
     118             :   /**
     119             :    * Place frames in the block direction (CSS property vertical-align)
     120             :    */
     121             :   void VerticalAlignLine();
     122             : 
     123             :   bool TrimTrailingWhiteSpace();
     124             : 
     125             :   /**
     126             :    * Place frames in the inline direction (CSS property text-align).
     127             :    */
     128             :   void TextAlignLine(nsLineBox* aLine, bool aIsLastLine);
     129             : 
     130             :   /**
     131             :    * Handle all the relative positioning in the line, compute the
     132             :    * combined area (== overflow area) for the line, and handle view
     133             :    * sizing/positioning and the setting of the overflow rect.
     134             :    */
     135          75 :   void RelativePositionFrames(nsOverflowAreas& aOverflowAreas)
     136             :   {
     137          75 :     RelativePositionFrames(mRootSpan, aOverflowAreas);
     138          75 :   }
     139             : 
     140             :   // Support methods for word-wrapping during line reflow
     141             : 
     142           0 :   void SetJustificationInfo(const mozilla::JustificationInfo& aInfo)
     143             :   {
     144           0 :     mJustificationInfo = aInfo;
     145           0 :   }
     146             : 
     147             :   /**
     148             :    * @return true if so far during reflow no non-empty content has been
     149             :    * placed in the line (according to nsIFrame::IsEmpty())
     150             :    */
     151         177 :   bool LineIsEmpty() const
     152             :   {
     153         177 :     return mLineIsEmpty;
     154             :   }
     155             : 
     156             :   /**
     157             :    * @return true if so far during reflow no non-empty leaf content
     158             :    * (non-collapsed whitespace, replaced element, inline-block, etc) has been
     159             :    * placed in the line
     160             :    */
     161          24 :   bool LineAtStart() const
     162             :   {
     163          24 :     return mLineAtStart;
     164             :   }
     165             : 
     166             :   bool LineIsBreakable() const;
     167             : 
     168          18 :   bool GetLineEndsInBR() const
     169             :   {
     170          18 :     return mLineEndsInBR;
     171             :   }
     172             : 
     173           9 :   void SetLineEndsInBR(bool aOn)
     174             :   {
     175           9 :     mLineEndsInBR = aOn;
     176           9 :   }
     177             : 
     178             :   //----------------------------------------
     179             :   // Inform the line-layout about the presence of a floating frame
     180             :   // XXX get rid of this: use get-frame-type?
     181           0 :   bool AddFloat(nsIFrame* aFloat, nscoord aAvailableISize)
     182             :   {
     183             :     // When reflowing ruby text frames, no block reflow state is
     184             :     // provided to the line layout. However, floats should never be
     185             :     // associated with ruby text containers, hence this method should
     186             :     // not be called in that case.
     187           0 :     MOZ_ASSERT(mBlockRI,
     188             :                "Should not call this method if there is no block reflow state "
     189             :                "available");
     190           0 :     return mBlockRI->AddFloat(this, aFloat, aAvailableISize);
     191             :   }
     192             : 
     193          24 :   void SetTrimmableISize(nscoord aTrimmableISize) {
     194          24 :     mTrimmableISize = aTrimmableISize;
     195          24 :   }
     196             : 
     197             :   //----------------------------------------
     198             : 
     199           0 :   bool GetFirstLetterStyleOK() const {
     200           0 :     return mFirstLetterStyleOK;
     201             :   }
     202             : 
     203           0 :   void SetFirstLetterStyleOK(bool aSetting) {
     204           0 :     mFirstLetterStyleOK = aSetting;
     205           0 :   }
     206             : 
     207          24 :   bool GetInFirstLetter() const {
     208          24 :     return mInFirstLetter;
     209             :   }
     210             : 
     211           0 :   void SetInFirstLetter(bool aSetting) {
     212           0 :     mInFirstLetter = aSetting;
     213           0 :   }
     214             : 
     215          24 :   bool GetInFirstLine() const {
     216          24 :     return mInFirstLine;
     217             :   }
     218             : 
     219           0 :   void SetInFirstLine(bool aSetting) {
     220           0 :     mInFirstLine = aSetting;
     221           0 :   }
     222             : 
     223             :   // Calling this during block reflow ensures that the next line of inlines
     224             :   // will be marked dirty, if there is one.
     225           0 :   void SetDirtyNextLine() {
     226           0 :     mDirtyNextLine = true;
     227           0 :   }
     228          75 :   bool GetDirtyNextLine() {
     229          75 :     return mDirtyNextLine;
     230             :   }
     231             : 
     232             :   //----------------------------------------
     233             : 
     234             :   nsPresContext* mPresContext;
     235             : 
     236             :   /**
     237             :    * Record where an optional break could have been placed. During line reflow,
     238             :    * frames containing optional break points (e.g., whitespace in text frames)
     239             :    * can call SetLastOptionalBreakPosition to record where a break could
     240             :    * have been made, but wasn't because we decided to place more content on
     241             :    * the line. For non-text frames, offset 0 means before the frame, offset
     242             :    * INT32_MAX means after the frame.
     243             :    *
     244             :    * Currently this is used to handle cases where a single word comprises
     245             :    * multiple frames, and the first frame fits on the line but the whole word
     246             :    * doesn't. We look back to the last optional break position and
     247             :    * reflow the whole line again, forcing a break at that position. The last
     248             :    * optional break position could be in a text frame or else after a frame
     249             :    * that cannot be part of a text run, so those are the positions we record.
     250             :    *
     251             :    * @param aFrame the frame which contains the optional break position.
     252             :    *
     253             :    * @param aFits set to true if the break position is within the available width.
     254             :    *
     255             :    * @param aPriority the priority of the break opportunity. If we are
     256             :    * prioritizing break opportunities, we will not set a break if we have
     257             :    * already set a break with a higher priority. @see gfxBreakPriority.
     258             :    *
     259             :    * @return true if we are actually reflowing with forced break position and we
     260             :    * should break here
     261             :    */
     262          19 :   bool NotifyOptionalBreakPosition(nsIFrame* aFrame, int32_t aOffset,
     263             :                                    bool aFits, gfxBreakPriority aPriority) {
     264          19 :     NS_ASSERTION(!aFits || !mNeedBackup,
     265             :                   "Shouldn't be updating the break position with a break that fits after we've already flagged an overrun");
     266             :     // Remember the last break position that fits; if there was no break that fit,
     267             :     // just remember the first break
     268          19 :     if ((aFits && aPriority >= mLastOptionalBreakPriority) ||
     269           0 :         !mLastOptionalBreakFrame) {
     270          19 :       mLastOptionalBreakFrame = aFrame;
     271          19 :       mLastOptionalBreakFrameOffset = aOffset;
     272          19 :       mLastOptionalBreakPriority = aPriority;
     273             :     }
     274          19 :     return aFrame && mForceBreakFrame == aFrame &&
     275          19 :       mForceBreakFrameOffset == aOffset;
     276             :   }
     277             :   /**
     278             :    * Like NotifyOptionalBreakPosition, but here it's OK for mNeedBackup
     279             :    * to be set, because the caller is merely pruning some saved break position(s)
     280             :    * that are actually not feasible.
     281             :    */
     282           0 :   void RestoreSavedBreakPosition(nsIFrame* aFrame, int32_t aOffset,
     283             :                                  gfxBreakPriority aPriority) {
     284           0 :     mLastOptionalBreakFrame = aFrame;
     285           0 :     mLastOptionalBreakFrameOffset = aOffset;
     286           0 :     mLastOptionalBreakPriority = aPriority;
     287           0 :   }
     288             :   /**
     289             :    * Signal that no backing up will be required after all.
     290             :    */
     291          75 :   void ClearOptionalBreakPosition() {
     292          75 :     mNeedBackup = false;
     293          75 :     mLastOptionalBreakFrame = nullptr;
     294          75 :     mLastOptionalBreakFrameOffset = -1;
     295          75 :     mLastOptionalBreakPriority = gfxBreakPriority::eNoBreak;
     296          75 :   }
     297             :   // Retrieve last set optional break position. When this returns null, no
     298             :   // optional break has been recorded (which means that the line can't break yet).
     299          75 :   nsIFrame* GetLastOptionalBreakPosition(int32_t* aOffset,
     300             :                                          gfxBreakPriority* aPriority) {
     301          75 :     *aOffset = mLastOptionalBreakFrameOffset;
     302          75 :     *aPriority = mLastOptionalBreakPriority;
     303          75 :     return mLastOptionalBreakFrame;
     304             :   }
     305             :   // Whether any optional break position has been recorded.
     306           0 :   bool HasOptionalBreakPosition() const
     307             :   {
     308           0 :     return mLastOptionalBreakFrame != nullptr;
     309             :   }
     310             :   // Get the priority of the last optional break position recorded.
     311          24 :   gfxBreakPriority LastOptionalBreakPriority() const
     312             :   {
     313          24 :     return mLastOptionalBreakPriority;
     314             :   }
     315             : 
     316             :   /**
     317             :    * Check whether frames overflowed the available width and CanPlaceFrame
     318             :    * requested backing up to a saved break position.
     319             :    */
     320          75 :   bool NeedsBackup() { return mNeedBackup; }
     321             : 
     322             :   // Line layout may place too much content on a line, overflowing its available
     323             :   // width. When that happens, if SetLastOptionalBreakPosition has been
     324             :   // used to record an optional break that wasn't taken, we can reflow the line
     325             :   // again and force the break to happen at that point (i.e., backtracking
     326             :   // to the last choice point).
     327             : 
     328             :   // Record that we want to break at the given content+offset (which
     329             :   // should have been previously returned by GetLastOptionalBreakPosition
     330             :   // from another nsLineLayout).
     331           0 :   void ForceBreakAtPosition(nsIFrame* aFrame, int32_t aOffset) {
     332           0 :     mForceBreakFrame = aFrame;
     333           0 :     mForceBreakFrameOffset = aOffset;
     334           0 :   }
     335           0 :   bool HaveForcedBreakPosition() { return mForceBreakFrame != nullptr; }
     336          24 :   int32_t GetForcedBreakPosition(nsIFrame* aFrame) {
     337          24 :     return mForceBreakFrame == aFrame ? mForceBreakFrameOffset : -1;
     338             :   }
     339             : 
     340             :   /**
     341             :    * This can't be null. It usually returns a block frame but may return
     342             :    * some other kind of frame when inline frames are reflowed in a non-block
     343             :    * context (e.g. MathML or floating first-letter).
     344             :    */
     345          24 :   nsIFrame* LineContainerFrame() const { return mBlockReflowInput->mFrame; }
     346          24 :   const ReflowInput* LineContainerRI() const { return mBlockReflowInput; }
     347             :   const nsLineList::iterator* GetLine() const {
     348             :     return mGotLineBox ? &mLineBox : nullptr;
     349             :   }
     350          24 :   nsLineList::iterator* GetLine() {
     351          24 :     return mGotLineBox ? &mLineBox : nullptr;
     352             :   }
     353             : 
     354             :   /**
     355             :    * Returns the accumulated advance width of frames before the current frame
     356             :    * on the line, plus the line container's left border+padding.
     357             :    * This is always positive, the advance width is measured from
     358             :    * the right edge for RTL blocks and from the left edge for LTR blocks.
     359             :    * In other words, the current frame's distance from the line container's
     360             :    * start content edge is:
     361             :    * <code>GetCurrentFrameInlineDistanceFromBlock() - lineContainer->GetUsedBorderAndPadding().left</code>
     362             :    * Note the use of <code>.left</code> for both LTR and RTL line containers.
     363             :    */
     364             :   nscoord GetCurrentFrameInlineDistanceFromBlock();
     365             : 
     366             :   /**
     367             :    * Move the inline position where the next frame will be reflowed forward by
     368             :    * aAmount.
     369             :    */
     370           0 :   void AdvanceICoord(nscoord aAmount) { mCurrentSpan->mICoord += aAmount; }
     371             :   /**
     372             :    * Returns the writing mode for the root span.
     373             :    */
     374           0 :   mozilla::WritingMode GetWritingMode() { return mRootSpan->mWritingMode; }
     375             :   /**
     376             :    * Returns the inline position where the next frame will be reflowed.
     377             :    */
     378           0 :   nscoord GetCurrentICoord() { return mCurrentSpan->mICoord; }
     379             : 
     380           0 :   void SetSuppressLineWrap(bool aEnabled) { mSuppressLineWrap = aEnabled; }
     381             : 
     382             : protected:
     383             :   // This state is constant for a given block frame doing line layout
     384             : 
     385             :   // A non-owning pointer, which points to the object owned by
     386             :   // nsAutoFloatManager::mNew.
     387             :   nsFloatManager* mFloatManager;
     388             : 
     389             :   const nsStyleText* mStyleText; // for the block
     390             :   const ReflowInput* mBlockReflowInput;
     391             : 
     392             :   // The line layout for the base text.  It is usually nullptr.
     393             :   // It becomes not null when the current line layout is for ruby
     394             :   // annotations. When there is nested ruby inside annotation, it
     395             :   // forms a linked list from the inner annotation to the outermost
     396             :   // line layout. The outermost line layout, which has this member
     397             :   // being nullptr, is responsible for managing the life cycle of
     398             :   // per-frame data and per-span data, and handling floats.
     399             :   nsLineLayout* const mBaseLineLayout;
     400             : 
     401         450 :   nsLineLayout* GetOutermostLineLayout() {
     402         450 :     nsLineLayout* lineLayout = this;
     403         450 :     while (lineLayout->mBaseLineLayout) {
     404           0 :       lineLayout = lineLayout->mBaseLineLayout;
     405             :     }
     406         450 :     return lineLayout;
     407             :   }
     408             : 
     409             :   nsIFrame* mLastOptionalBreakFrame;
     410             :   nsIFrame* mForceBreakFrame;
     411             : 
     412             :   // XXX remove this when landing bug 154892 (splitting absolute positioned frames)
     413             :   friend class nsInlineFrame;
     414             : 
     415             :   // XXX Take care that nsRubyBaseContainer would give nullptr to this
     416             :   //     member. It should not be a problem currently, since the only
     417             :   //     code use it is handling float, which does not affect ruby.
     418             :   //     See comment in nsLineLayout::AddFloat
     419             :   BlockReflowInput* mBlockRI;/* XXX hack! */
     420             : 
     421             :   nsLineList::iterator mLineBox;
     422             : 
     423             :   // Per-frame data recorded by the line-layout reflow logic. This
     424             :   // state is the state needed to post-process the line after reflow
     425             :   // has completed (block-direction alignment, inline-direction alignment,
     426             :   // justification and relative positioning).
     427             : 
     428             :   struct PerSpanData;
     429             :   struct PerFrameData;
     430             :   friend struct PerSpanData;
     431             :   friend struct PerFrameData;
     432             :   struct PerFrameData
     433             :   {
     434             :     // link to next/prev frame in same span
     435             :     PerFrameData* mNext;
     436             :     PerFrameData* mPrev;
     437             : 
     438             :     // Link to the frame of next ruby annotation.  It is a linked list
     439             :     // through this pointer from ruby base to all its annotations.  It
     440             :     // could be nullptr if there is no more annotation.
     441             :     // If PFD_ISLINKEDTOBASE is set, the current PFD is one of the ruby
     442             :     // annotations in the base's list, otherwise it is the ruby base,
     443             :     // and its mNextAnnotation is the start of the linked list.
     444             :     PerFrameData* mNextAnnotation;
     445             : 
     446             :     // pointer to child span data if this is an inline container frame
     447             :     PerSpanData* mSpan;
     448             : 
     449             :     // The frame
     450             :     nsIFrame* mFrame;
     451             : 
     452             :     // From metrics
     453             :     nscoord mAscent;
     454             :     // note that mBounds is a logical rect in the *line*'s writing mode.
     455             :     // When setting frame coordinates, we have to convert to the frame's
     456             :     //  writing mode
     457             :     mozilla::LogicalRect mBounds;
     458             :     nsOverflowAreas mOverflowAreas;
     459             : 
     460             :     // From reflow-state
     461             :     mozilla::LogicalMargin mMargin;        // in *line* writing mode
     462             :     mozilla::LogicalMargin mBorderPadding; // in *line* writing mode
     463             :     mozilla::LogicalMargin mOffsets;       // in *frame* writing mode
     464             : 
     465             :     // state for text justification
     466             :     // Note that, although all frames would have correct inner
     467             :     // opportunities computed after ComputeFrameJustification, start
     468             :     // and end justifiable info are not reliable for non-text frames.
     469             :     mozilla::JustificationInfo mJustificationInfo;
     470             :     mozilla::JustificationAssignment mJustificationAssignment;
     471             : 
     472             :     // PerFrameData flags
     473             :     bool mRelativePos : 1;
     474             :     bool mIsTextFrame : 1;
     475             :     bool mIsNonEmptyTextFrame : 1;
     476             :     bool mIsNonWhitespaceTextFrame : 1;
     477             :     bool mIsLetterFrame : 1;
     478             :     bool mRecomputeOverflow : 1;
     479             :     bool mIsBullet : 1;
     480             :     bool mSkipWhenTrimmingWhitespace : 1;
     481             :     bool mIsEmpty : 1;
     482             :     bool mIsLinkedToBase : 1;
     483             : 
     484             :     // Other state we use
     485             :     uint8_t mBlockDirAlign;
     486             :     mozilla::WritingMode mWritingMode;
     487             : 
     488          75 :     PerFrameData* Last() {
     489          75 :       PerFrameData* pfd = this;
     490          75 :       while (pfd->mNext) {
     491           0 :         pfd = pfd->mNext;
     492             :       }
     493          75 :       return pfd;
     494             :     }
     495             : 
     496             :     bool IsStartJustifiable() const
     497             :     {
     498             :       return mJustificationInfo.mIsStartJustifiable;
     499             :     }
     500             : 
     501             :     bool IsEndJustifiable() const
     502             :     {
     503             :       return mJustificationInfo.mIsEndJustifiable;
     504             :     }
     505             : 
     506             :     bool ParticipatesInJustification() const;
     507             :   };
     508             :   PerFrameData* mFrameFreeList;
     509             : 
     510             :   // In nsLineLayout, a "span" is a container inline frame, and a "frame" is one
     511             :   // of its children.
     512             :   //
     513             :   // nsLineLayout::BeginLineReflow() creates the initial PerSpanData which is
     514             :   // called the "root span". nsInlineFrame::ReflowFrames() creates a new
     515             :   // PerSpanData when it calls nsLineLayout::BeginSpan(); at this time, the
     516             :   // nsLineLayout object's mCurrentSpan is switched to the new span. The new
     517             :   // span records the old mCurrentSpan as its parent. After reflowing the child
     518             :   // inline frames, nsInlineFrame::ReflowFrames() calls nsLineLayout::EndSpan(),
     519             :   // which pops the PerSpanData and re-sets mCurrentSpan.
     520             :   struct PerSpanData {
     521             :     union {
     522             :       PerSpanData* mParent;
     523             :       PerSpanData* mNextFreeSpan;
     524             :     };
     525             : 
     526             :     // The PerFrameData of the inline frame that "owns" the span, or null if
     527             :     // this is the root span. mFrame is initialized to the containing inline
     528             :     // frame's PerFrameData when a new PerSpanData is pushed in
     529             :     // nsLineLayout::BeginSpan().
     530             :     PerFrameData* mFrame;
     531             : 
     532             :     // The first PerFrameData structure in the span.
     533             :     PerFrameData* mFirstFrame;
     534             : 
     535             :     // The last PerFrameData structure in the span. PerFrameData structures are
     536             :     // added to the span as they are reflowed. mLastFrame may also be directly
     537             :     // manipulated if a line is split, or if frames are pushed from one line to
     538             :     // the next.
     539             :     PerFrameData* mLastFrame;
     540             : 
     541             :     const ReflowInput* mReflowInput;
     542             :     bool mNoWrap;
     543             :     mozilla::WritingMode mWritingMode;
     544             :     bool mContainsFloat;
     545             :     bool mHasNonemptyContent;
     546             : 
     547             :     nscoord mIStart;
     548             :     nscoord mICoord;
     549             :     nscoord mIEnd;
     550             : 
     551             :     nscoord mBStartLeading, mBEndLeading;
     552             :     nscoord mLogicalBSize;
     553             :     nscoord mMinBCoord, mMaxBCoord;
     554             :     nscoord* mBaseline;
     555             : 
     556          75 :     void AppendFrame(PerFrameData* pfd) {
     557          75 :       if (nullptr == mLastFrame) {
     558          75 :         mFirstFrame = pfd;
     559             :       }
     560             :       else {
     561           0 :         mLastFrame->mNext = pfd;
     562           0 :         pfd->mPrev = mLastFrame;
     563             :       }
     564          75 :       mLastFrame = pfd;
     565          75 :     }
     566             :   };
     567             :   PerSpanData* mSpanFreeList;
     568             :   PerSpanData* mRootSpan;
     569             :   PerSpanData* mCurrentSpan;
     570             : 
     571             :   // The container size to use when converting between logical and
     572             :   // physical coordinates for frames in this span. For the root span
     573             :   // this is the size of the block cached in mContainerSize; for
     574             :   // child spans it's the size of the root span.
     575         150 :   nsSize ContainerSizeForSpan(PerSpanData* aPSD) {
     576         150 :     return (aPSD == mRootSpan)
     577             :       ? mContainerSize
     578         150 :       : aPSD->mFrame->mBounds.Size(mRootSpan->mWritingMode).
     579         450 :         GetPhysicalSize(mRootSpan->mWritingMode);
     580             :   }
     581             : 
     582             :   gfxBreakPriority mLastOptionalBreakPriority;
     583             :   int32_t     mLastOptionalBreakFrameOffset;
     584             :   int32_t     mForceBreakFrameOffset;
     585             : 
     586             :   nscoord mMinLineBSize;
     587             : 
     588             :   // The amount of text indent that we applied to this line, needed for
     589             :   // max-element-size calculation.
     590             :   nscoord mTextIndent;
     591             : 
     592             :   // This state varies during the reflow of a line but is line
     593             :   // "global" state not span "local" state.
     594             :   int32_t mLineNumber;
     595             :   mozilla::JustificationInfo mJustificationInfo;
     596             : 
     597             :   int32_t mTotalPlacedFrames;
     598             : 
     599             :   nscoord mBStartEdge;
     600             :   nscoord mMaxStartBoxBSize;
     601             :   nscoord mMaxEndBoxBSize;
     602             : 
     603             :   nscoord mInflationMinFontSize;
     604             : 
     605             :   // Final computed line-bSize value after VerticalAlignFrames for
     606             :   // the block has been called.
     607             :   nscoord mFinalLineBSize;
     608             : 
     609             :   // Amount of trimmable whitespace inline size for the trailing text
     610             :   // frame, if any
     611             :   nscoord mTrimmableISize;
     612             : 
     613             :   // Physical size. Use only for physical <-> logical coordinate conversion.
     614             :   nsSize mContainerSize;
     615         300 :   const nsSize& ContainerSize() const { return mContainerSize; }
     616             : 
     617             :   bool mFirstLetterStyleOK      : 1;
     618             :   bool mIsTopOfPage             : 1;
     619             :   bool mImpactedByFloats        : 1;
     620             :   bool mLastFloatWasLetterFrame : 1;
     621             :   bool mLineIsEmpty             : 1;
     622             :   bool mLineEndsInBR            : 1;
     623             :   bool mNeedBackup              : 1;
     624             :   bool mInFirstLine             : 1;
     625             :   bool mGotLineBox              : 1;
     626             :   bool mInFirstLetter           : 1;
     627             :   bool mHasBullet               : 1;
     628             :   bool mDirtyNextLine           : 1;
     629             :   bool mLineAtStart             : 1;
     630             :   bool mHasRuby                 : 1;
     631             :   bool mSuppressLineWrap        : 1;
     632             : 
     633             :   int32_t mSpanDepth;
     634             : #ifdef DEBUG
     635             :   int32_t mSpansAllocated, mSpansFreed;
     636             :   int32_t mFramesAllocated, mFramesFreed;
     637             : #endif
     638             : 
     639             :   /**
     640             :    * Per span and per frame data.
     641             :    */
     642             :   mozilla::ArenaAllocator<1024, sizeof(void*)> mArena;
     643             : 
     644             :   /**
     645             :    * Allocate a PerFrameData from the mArena pool. The allocation is infallible.
     646             :    */
     647             :   PerFrameData* NewPerFrameData(nsIFrame* aFrame);
     648             : 
     649             :   /**
     650             :    * Allocate a PerSpanData from the mArena pool. The allocation is infallible.
     651             :    */
     652             :   PerSpanData* NewPerSpanData();
     653             : 
     654           0 :   PerFrameData* LastFrame() const { return mCurrentSpan->mLastFrame; }
     655             : 
     656             :   /**
     657             :    * Unlink the given PerFrameData and all the siblings after it from
     658             :    * the span. The unlinked PFDs are usually freed immediately.
     659             :    * However, if PFD_ISLINKEDTOBASE is set, it won't be freed until
     660             :    * the frame of its base is unlinked.
     661             :    */
     662             :   void UnlinkFrame(PerFrameData* pfd);
     663             : 
     664             :   /**
     665             :    * Free the given PerFrameData.
     666             :    */
     667             :   void FreeFrame(PerFrameData* pfd);
     668             : 
     669             :   void FreeSpan(PerSpanData* psd);
     670             : 
     671             :   bool InBlockContext() const {
     672             :     return mSpanDepth == 0;
     673             :   }
     674             : 
     675             :   void PushFrame(nsIFrame* aFrame);
     676             : 
     677             :   void AllowForStartMargin(PerFrameData* pfd,
     678             :                            ReflowInput& aReflowInput);
     679             : 
     680             :   void SyncAnnotationBounds(PerFrameData* aRubyFrame);
     681             : 
     682             :   bool CanPlaceFrame(PerFrameData* pfd,
     683             :                        bool aNotSafeToBreak,
     684             :                        bool aFrameCanContinueTextRun,
     685             :                        bool aCanRollBackBeforeFrame,
     686             :                        ReflowOutput& aMetrics,
     687             :                        nsReflowStatus& aStatus,
     688             :                        bool* aOptionalBreakAfterFits);
     689             : 
     690             :   void PlaceFrame(PerFrameData* pfd,
     691             :                   ReflowOutput& aMetrics);
     692             : 
     693             :   void AdjustLeadings(nsIFrame* spanFrame, PerSpanData* psd,
     694             :                       const nsStyleText* aStyleText, float aInflation,
     695             :                       bool* aZeroEffectiveSpanBox);
     696             : 
     697             :   void VerticalAlignFrames(PerSpanData* psd);
     698             : 
     699             :   void PlaceTopBottomFrames(PerSpanData* psd,
     700             :                             nscoord aDistanceFromStart,
     701             :                             nscoord aLineBSize);
     702             : 
     703             :   void ApplyRelativePositioning(PerFrameData* aPFD);
     704             : 
     705             :   void RelativePositionAnnotations(PerSpanData* aRubyPSD,
     706             :                                    nsOverflowAreas& aOverflowAreas);
     707             : 
     708             :   void RelativePositionFrames(PerSpanData* psd, nsOverflowAreas& aOverflowAreas);
     709             : 
     710             :   bool TrimTrailingWhiteSpaceIn(PerSpanData* psd, nscoord* aDeltaISize);
     711             : 
     712             :   struct JustificationComputationState;
     713             : 
     714             :   static int AssignInterframeJustificationGaps(
     715             :     PerFrameData* aFrame, JustificationComputationState& aState);
     716             : 
     717             :   int32_t ComputeFrameJustification(PerSpanData* psd,
     718             :                                     JustificationComputationState& aState);
     719             : 
     720             :   void AdvanceAnnotationInlineBounds(PerFrameData* aPFD,
     721             :                                      const nsSize& aContainerSize,
     722             :                                      nscoord aDeltaICoord,
     723             :                                      nscoord aDeltaISize);
     724             : 
     725             :   void ApplyLineJustificationToAnnotations(PerFrameData* aPFD,
     726             :                                            nscoord aDeltaICoord,
     727             :                                            nscoord aDeltaISize);
     728             : 
     729             :   // Apply justification.  The return value is the amount by which the width of
     730             :   // the span corresponding to aPSD got increased due to justification.
     731             :   nscoord ApplyFrameJustification(
     732             :       PerSpanData* aPSD, mozilla::JustificationApplicationState& aState);
     733             : 
     734             :   void ExpandRubyBox(PerFrameData* aFrame, nscoord aReservedISize,
     735             :                      const nsSize& aContainerSize);
     736             : 
     737             :   void ExpandRubyBoxWithAnnotations(PerFrameData* aFrame,
     738             :                                     const nsSize& aContainerSize);
     739             : 
     740             :   void ExpandInlineRubyBoxes(PerSpanData* aSpan);
     741             : 
     742             :   void AttachFrameToBaseLineLayout(PerFrameData* aFrame);
     743             : 
     744             : #ifdef DEBUG
     745             :   void DumpPerSpanData(PerSpanData* psd, int32_t aIndent);
     746             : #endif
     747             : };
     748             : 
     749             : #endif /* nsLineLayout_h___ */

Generated by: LCOV version 1.13