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___ */