layout/generic/nsLineLayout.h

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
michael@0 2 * vim:cindent:ts=2:et:sw=2:
michael@0 3 *
michael@0 4 * This Source Code Form is subject to the terms of the Mozilla Public
michael@0 5 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 6 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
michael@0 7 * This Original Code has been modified by IBM Corporation. Modifications made by IBM
michael@0 8 * described herein are Copyright (c) International Business Machines Corporation, 2000.
michael@0 9 * Modifications to Mozilla code or documentation identified per MPL Section 3.3
michael@0 10 *
michael@0 11 * Date Modified by Description of modification
michael@0 12 * 04/20/2000 IBM Corp. OS/2 VisualAge build.
michael@0 13 */
michael@0 14
michael@0 15 /* state and methods used while laying out a single line of a block frame */
michael@0 16
michael@0 17 #ifndef nsLineLayout_h___
michael@0 18 #define nsLineLayout_h___
michael@0 19
michael@0 20 #include "nsLineBox.h"
michael@0 21 #include "nsBlockReflowState.h"
michael@0 22 #include "plarena.h"
michael@0 23 #include "gfxTypes.h"
michael@0 24 #include "WritingModes.h"
michael@0 25
michael@0 26 class nsFloatManager;
michael@0 27 struct nsStyleText;
michael@0 28
michael@0 29 class nsLineLayout {
michael@0 30 public:
michael@0 31 nsLineLayout(nsPresContext* aPresContext,
michael@0 32 nsFloatManager* aFloatManager,
michael@0 33 const nsHTMLReflowState* aOuterReflowState,
michael@0 34 const nsLineList::iterator* aLine);
michael@0 35 ~nsLineLayout();
michael@0 36
michael@0 37 void Init(nsBlockReflowState* aState, nscoord aMinLineBSize,
michael@0 38 int32_t aLineNumber) {
michael@0 39 mBlockRS = aState;
michael@0 40 mMinLineBSize = aMinLineBSize;
michael@0 41 mLineNumber = aLineNumber;
michael@0 42 }
michael@0 43
michael@0 44 int32_t GetLineNumber() const {
michael@0 45 return mLineNumber;
michael@0 46 }
michael@0 47
michael@0 48 void BeginLineReflow(nscoord aICoord, nscoord aBCoord,
michael@0 49 nscoord aISize, nscoord aBSize,
michael@0 50 bool aImpactedByFloats,
michael@0 51 bool aIsTopOfPage,
michael@0 52 mozilla::WritingMode aWritingMode,
michael@0 53 nscoord aContainerWidth);
michael@0 54
michael@0 55 void EndLineReflow();
michael@0 56
michael@0 57 /**
michael@0 58 * Called when a float has been placed. This method updates the
michael@0 59 * inline frame and span data to account for any change in positions
michael@0 60 * due to available space for the line boxes changing.
michael@0 61 * @param aX/aY/aWidth/aHeight are the new available
michael@0 62 * space rectangle, relative to the containing block.
michael@0 63 * @param aFloatFrame the float frame that was placed.
michael@0 64 */
michael@0 65 void UpdateBand(const nsRect& aNewAvailableSpace,
michael@0 66 nsIFrame* aFloatFrame);
michael@0 67
michael@0 68 void BeginSpan(nsIFrame* aFrame, const nsHTMLReflowState* aSpanReflowState,
michael@0 69 nscoord aLeftEdge, nscoord aRightEdge, nscoord* aBaseline);
michael@0 70
michael@0 71 // Returns the width of the span
michael@0 72 nscoord EndSpan(nsIFrame* aFrame);
michael@0 73
michael@0 74 int32_t GetCurrentSpanCount() const;
michael@0 75
michael@0 76 void SplitLineTo(int32_t aNewCount);
michael@0 77
michael@0 78 bool IsZeroBSize();
michael@0 79
michael@0 80 // Reflows the frame and returns the reflow status. aPushedFrame is true
michael@0 81 // if the frame is pushed to the next line because it doesn't fit
michael@0 82 nsresult ReflowFrame(nsIFrame* aFrame,
michael@0 83 nsReflowStatus& aReflowStatus,
michael@0 84 nsHTMLReflowMetrics* aMetrics,
michael@0 85 bool& aPushedFrame);
michael@0 86
michael@0 87 void AddBulletFrame(nsIFrame* aFrame, const nsHTMLReflowMetrics& aMetrics);
michael@0 88
michael@0 89 void RemoveBulletFrame(nsIFrame* aFrame) {
michael@0 90 PushFrame(aFrame);
michael@0 91 }
michael@0 92
michael@0 93 void BlockDirAlignLine();
michael@0 94
michael@0 95 bool TrimTrailingWhiteSpace();
michael@0 96
michael@0 97 void InlineDirAlignFrames(nsLineBox* aLine, bool aIsLastLine);
michael@0 98
michael@0 99 /**
michael@0 100 * Handle all the relative positioning in the line, compute the
michael@0 101 * combined area (== overflow area) for the line, and handle view
michael@0 102 * sizing/positioning and the setting of the overflow rect.
michael@0 103 */
michael@0 104 void RelativePositionFrames(nsOverflowAreas& aOverflowAreas);
michael@0 105
michael@0 106 // Support methods for word-wrapping during line reflow
michael@0 107
michael@0 108 void SetTextJustificationWeights(int32_t aNumSpaces, int32_t aNumLetters) {
michael@0 109 mTextJustificationNumSpaces = aNumSpaces;
michael@0 110 mTextJustificationNumLetters = aNumLetters;
michael@0 111 }
michael@0 112
michael@0 113 /**
michael@0 114 * @return true if so far during reflow no non-empty content has been
michael@0 115 * placed in the line (according to nsIFrame::IsEmpty())
michael@0 116 */
michael@0 117 bool LineIsEmpty() const
michael@0 118 {
michael@0 119 return mLineIsEmpty;
michael@0 120 }
michael@0 121
michael@0 122 /**
michael@0 123 * @return true if so far during reflow no non-empty leaf content
michael@0 124 * (non-collapsed whitespace, replaced element, inline-block, etc) has been
michael@0 125 * placed in the line
michael@0 126 */
michael@0 127 bool LineAtStart() const
michael@0 128 {
michael@0 129 return mLineAtStart;
michael@0 130 }
michael@0 131
michael@0 132 bool LineIsBreakable() const;
michael@0 133
michael@0 134 bool GetLineEndsInBR() const
michael@0 135 {
michael@0 136 return mLineEndsInBR;
michael@0 137 }
michael@0 138
michael@0 139 void SetLineEndsInBR(bool aOn)
michael@0 140 {
michael@0 141 mLineEndsInBR = aOn;
michael@0 142 }
michael@0 143
michael@0 144 //----------------------------------------
michael@0 145 // Inform the line-layout about the presence of a floating frame
michael@0 146 // XXX get rid of this: use get-frame-type?
michael@0 147 bool AddFloat(nsIFrame* aFloat, nscoord aAvailableWidth)
michael@0 148 {
michael@0 149 return mBlockRS->AddFloat(this, aFloat, aAvailableWidth);
michael@0 150 }
michael@0 151
michael@0 152 void SetTrimmableWidth(nscoord aTrimmableWidth) {
michael@0 153 mTrimmableWidth = aTrimmableWidth;
michael@0 154 }
michael@0 155
michael@0 156 //----------------------------------------
michael@0 157
michael@0 158 bool GetFirstLetterStyleOK() const {
michael@0 159 return mFirstLetterStyleOK;
michael@0 160 }
michael@0 161
michael@0 162 void SetFirstLetterStyleOK(bool aSetting) {
michael@0 163 mFirstLetterStyleOK = aSetting;
michael@0 164 }
michael@0 165
michael@0 166 bool GetInFirstLetter() const {
michael@0 167 return mInFirstLetter;
michael@0 168 }
michael@0 169
michael@0 170 void SetInFirstLetter(bool aSetting) {
michael@0 171 mInFirstLetter = aSetting;
michael@0 172 }
michael@0 173
michael@0 174 bool GetInFirstLine() const {
michael@0 175 return mInFirstLine;
michael@0 176 }
michael@0 177
michael@0 178 void SetInFirstLine(bool aSetting) {
michael@0 179 mInFirstLine = aSetting;
michael@0 180 }
michael@0 181
michael@0 182 // Calling this during block reflow ensures that the next line of inlines
michael@0 183 // will be marked dirty, if there is one.
michael@0 184 void SetDirtyNextLine() {
michael@0 185 mDirtyNextLine = true;
michael@0 186 }
michael@0 187 bool GetDirtyNextLine() {
michael@0 188 return mDirtyNextLine;
michael@0 189 }
michael@0 190
michael@0 191 //----------------------------------------
michael@0 192
michael@0 193 nsPresContext* mPresContext;
michael@0 194
michael@0 195 /**
michael@0 196 * Record where an optional break could have been placed. During line reflow,
michael@0 197 * frames containing optional break points (e.g., whitespace in text frames)
michael@0 198 * can call SetLastOptionalBreakPosition to record where a break could
michael@0 199 * have been made, but wasn't because we decided to place more content on
michael@0 200 * the line. For non-text frames, offset 0 means
michael@0 201 * before the content, offset INT32_MAX means after the content.
michael@0 202 *
michael@0 203 * Currently this is used to handle cases where a single word comprises
michael@0 204 * multiple frames, and the first frame fits on the line but the whole word
michael@0 205 * doesn't. We look back to the last optional break position and
michael@0 206 * reflow the whole line again, forcing a break at that position. The last
michael@0 207 * optional break position could be in a text frame or else after a frame
michael@0 208 * that cannot be part of a text run, so those are the positions we record.
michael@0 209 *
michael@0 210 * @param aFits set to true if the break position is within the available width.
michael@0 211 *
michael@0 212 * @param aPriority the priority of the break opportunity. If we are
michael@0 213 * prioritizing break opportunities, we will not set a break if we have
michael@0 214 * already set a break with a higher priority. @see gfxBreakPriority.
michael@0 215 *
michael@0 216 * @return true if we are actually reflowing with forced break position and we
michael@0 217 * should break here
michael@0 218 */
michael@0 219 bool NotifyOptionalBreakPosition(nsIContent* aContent, int32_t aOffset,
michael@0 220 bool aFits, gfxBreakPriority aPriority) {
michael@0 221 NS_ASSERTION(!aFits || !mNeedBackup,
michael@0 222 "Shouldn't be updating the break position with a break that fits after we've already flagged an overrun");
michael@0 223 // Remember the last break position that fits; if there was no break that fit,
michael@0 224 // just remember the first break
michael@0 225 if ((aFits && aPriority >= mLastOptionalBreakPriority) ||
michael@0 226 !mLastOptionalBreakContent) {
michael@0 227 mLastOptionalBreakContent = aContent;
michael@0 228 mLastOptionalBreakContentOffset = aOffset;
michael@0 229 mLastOptionalBreakPriority = aPriority;
michael@0 230 }
michael@0 231 return aContent && mForceBreakContent == aContent &&
michael@0 232 mForceBreakContentOffset == aOffset;
michael@0 233 }
michael@0 234 /**
michael@0 235 * Like NotifyOptionalBreakPosition, but here it's OK for mNeedBackup
michael@0 236 * to be set, because the caller is merely pruning some saved break position(s)
michael@0 237 * that are actually not feasible.
michael@0 238 */
michael@0 239 void RestoreSavedBreakPosition(nsIContent* aContent, int32_t aOffset,
michael@0 240 gfxBreakPriority aPriority) {
michael@0 241 mLastOptionalBreakContent = aContent;
michael@0 242 mLastOptionalBreakContentOffset = aOffset;
michael@0 243 mLastOptionalBreakPriority = aPriority;
michael@0 244 }
michael@0 245 /**
michael@0 246 * Signal that no backing up will be required after all.
michael@0 247 */
michael@0 248 void ClearOptionalBreakPosition() {
michael@0 249 mNeedBackup = false;
michael@0 250 mLastOptionalBreakContent = nullptr;
michael@0 251 mLastOptionalBreakContentOffset = -1;
michael@0 252 mLastOptionalBreakPriority = gfxBreakPriority::eNoBreak;
michael@0 253 }
michael@0 254 // Retrieve last set optional break position. When this returns null, no
michael@0 255 // optional break has been recorded (which means that the line can't break yet).
michael@0 256 nsIContent* GetLastOptionalBreakPosition(int32_t* aOffset,
michael@0 257 gfxBreakPriority* aPriority) {
michael@0 258 *aOffset = mLastOptionalBreakContentOffset;
michael@0 259 *aPriority = mLastOptionalBreakPriority;
michael@0 260 return mLastOptionalBreakContent;
michael@0 261 }
michael@0 262
michael@0 263 /**
michael@0 264 * Check whether frames overflowed the available width and CanPlaceFrame
michael@0 265 * requested backing up to a saved break position.
michael@0 266 */
michael@0 267 bool NeedsBackup() { return mNeedBackup; }
michael@0 268
michael@0 269 // Line layout may place too much content on a line, overflowing its available
michael@0 270 // width. When that happens, if SetLastOptionalBreakPosition has been
michael@0 271 // used to record an optional break that wasn't taken, we can reflow the line
michael@0 272 // again and force the break to happen at that point (i.e., backtracking
michael@0 273 // to the last choice point).
michael@0 274
michael@0 275 // Record that we want to break at the given content+offset (which
michael@0 276 // should have been previously returned by GetLastOptionalBreakPosition
michael@0 277 // from another nsLineLayout).
michael@0 278 void ForceBreakAtPosition(nsIContent* aContent, int32_t aOffset) {
michael@0 279 mForceBreakContent = aContent;
michael@0 280 mForceBreakContentOffset = aOffset;
michael@0 281 }
michael@0 282 bool HaveForcedBreakPosition() { return mForceBreakContent != nullptr; }
michael@0 283 int32_t GetForcedBreakPosition(nsIContent* aContent) {
michael@0 284 return mForceBreakContent == aContent ? mForceBreakContentOffset : -1;
michael@0 285 }
michael@0 286
michael@0 287 /**
michael@0 288 * This can't be null. It usually returns a block frame but may return
michael@0 289 * some other kind of frame when inline frames are reflowed in a non-block
michael@0 290 * context (e.g. MathML or floating first-letter).
michael@0 291 */
michael@0 292 nsIFrame* LineContainerFrame() const { return mBlockReflowState->frame; }
michael@0 293 const nsHTMLReflowState* LineContainerRS() const { return mBlockReflowState; }
michael@0 294 const nsLineList::iterator* GetLine() const {
michael@0 295 return mGotLineBox ? &mLineBox : nullptr;
michael@0 296 }
michael@0 297 nsLineList::iterator* GetLine() {
michael@0 298 return mGotLineBox ? &mLineBox : nullptr;
michael@0 299 }
michael@0 300
michael@0 301 /**
michael@0 302 * Returns the accumulated advance width of frames before the current frame
michael@0 303 * on the line, plus the line container's left border+padding.
michael@0 304 * This is always positive, the advance width is measured from
michael@0 305 * the right edge for RTL blocks and from the left edge for LTR blocks.
michael@0 306 * In other words, the current frame's distance from the line container's
michael@0 307 * start content edge is:
michael@0 308 * <code>GetCurrentFrameInlineDistanceFromBlock() - lineContainer->GetUsedBorderAndPadding().left</code>
michael@0 309 * Note the use of <code>.left</code> for both LTR and RTL line containers.
michael@0 310 */
michael@0 311 nscoord GetCurrentFrameInlineDistanceFromBlock();
michael@0 312
michael@0 313 protected:
michael@0 314 // This state is constant for a given block frame doing line layout
michael@0 315 nsFloatManager* mFloatManager;
michael@0 316 const nsStyleText* mStyleText; // for the block
michael@0 317 const nsHTMLReflowState* mBlockReflowState;
michael@0 318
michael@0 319 nsIContent* mLastOptionalBreakContent;
michael@0 320 nsIContent* mForceBreakContent;
michael@0 321
michael@0 322 // XXX remove this when landing bug 154892 (splitting absolute positioned frames)
michael@0 323 friend class nsInlineFrame;
michael@0 324
michael@0 325 nsBlockReflowState* mBlockRS;/* XXX hack! */
michael@0 326
michael@0 327 nsLineList::iterator mLineBox;
michael@0 328
michael@0 329 // Per-frame data recorded by the line-layout reflow logic. This
michael@0 330 // state is the state needed to post-process the line after reflow
michael@0 331 // has completed (block-direction alignment, inline-direction alignment,
michael@0 332 // justification and relative positioning).
michael@0 333
michael@0 334 struct PerSpanData;
michael@0 335 struct PerFrameData;
michael@0 336 friend struct PerSpanData;
michael@0 337 friend struct PerFrameData;
michael@0 338 struct PerFrameData
michael@0 339 {
michael@0 340 PerFrameData(mozilla::WritingMode aWritingMode)
michael@0 341 : mBounds(aWritingMode)
michael@0 342 , mMargin(aWritingMode)
michael@0 343 , mBorderPadding(aWritingMode)
michael@0 344 , mOffsets(aWritingMode)
michael@0 345 {}
michael@0 346
michael@0 347 // link to next/prev frame in same span
michael@0 348 PerFrameData* mNext;
michael@0 349 PerFrameData* mPrev;
michael@0 350
michael@0 351 // pointer to child span data if this is an inline container frame
michael@0 352 PerSpanData* mSpan;
michael@0 353
michael@0 354 // The frame
michael@0 355 nsIFrame* mFrame;
michael@0 356
michael@0 357 // From metrics
michael@0 358 nscoord mAscent;
michael@0 359 // note that mBounds is a logical rect in the *line*'s writing mode.
michael@0 360 // When setting frame coordinates, we have to convert to the frame's
michael@0 361 // writing mode
michael@0 362 mozilla::LogicalRect mBounds;
michael@0 363 nsOverflowAreas mOverflowAreas;
michael@0 364
michael@0 365 // From reflow-state
michael@0 366 mozilla::LogicalMargin mMargin;
michael@0 367 mozilla::LogicalMargin mBorderPadding;
michael@0 368 mozilla::LogicalMargin mOffsets;
michael@0 369
michael@0 370 // state for text justification
michael@0 371 int32_t mJustificationNumSpaces;
michael@0 372 int32_t mJustificationNumLetters;
michael@0 373
michael@0 374 // Other state we use
michael@0 375 uint8_t mBlockDirAlign;
michael@0 376
michael@0 377 // PerFrameData flags
michael@0 378 #define PFD_RELATIVEPOS 0x00000001
michael@0 379 #define PFD_ISTEXTFRAME 0x00000002
michael@0 380 #define PFD_ISNONEMPTYTEXTFRAME 0x00000004
michael@0 381 #define PFD_ISNONWHITESPACETEXTFRAME 0x00000008
michael@0 382 #define PFD_ISLETTERFRAME 0x00000010
michael@0 383 #define PFD_RECOMPUTEOVERFLOW 0x00000020
michael@0 384 #define PFD_ISBULLET 0x00000040
michael@0 385 #define PFD_SKIPWHENTRIMMINGWHITESPACE 0x00000080
michael@0 386 #define PFD_LASTFLAG PFD_SKIPWHENTRIMMINGWHITESPACE
michael@0 387
michael@0 388 uint8_t mFlags;
michael@0 389
michael@0 390 void SetFlag(uint32_t aFlag, bool aValue)
michael@0 391 {
michael@0 392 NS_ASSERTION(aFlag<=PFD_LASTFLAG, "bad flag");
michael@0 393 NS_ASSERTION(aFlag<=UINT8_MAX, "bad flag");
michael@0 394 if (aValue) { // set flag
michael@0 395 mFlags |= aFlag;
michael@0 396 }
michael@0 397 else { // unset flag
michael@0 398 mFlags &= ~aFlag;
michael@0 399 }
michael@0 400 }
michael@0 401
michael@0 402 bool GetFlag(uint32_t aFlag) const
michael@0 403 {
michael@0 404 NS_ASSERTION(aFlag<=PFD_LASTFLAG, "bad flag");
michael@0 405 return !!(mFlags & aFlag);
michael@0 406 }
michael@0 407
michael@0 408
michael@0 409 PerFrameData* Last() {
michael@0 410 PerFrameData* pfd = this;
michael@0 411 while (pfd->mNext) {
michael@0 412 pfd = pfd->mNext;
michael@0 413 }
michael@0 414 return pfd;
michael@0 415 }
michael@0 416 };
michael@0 417 PerFrameData* mFrameFreeList;
michael@0 418
michael@0 419 struct PerSpanData {
michael@0 420 union {
michael@0 421 PerSpanData* mParent;
michael@0 422 PerSpanData* mNextFreeSpan;
michael@0 423 };
michael@0 424 PerFrameData* mFrame;
michael@0 425 PerFrameData* mFirstFrame;
michael@0 426 PerFrameData* mLastFrame;
michael@0 427
michael@0 428 const nsHTMLReflowState* mReflowState;
michael@0 429 bool mNoWrap;
michael@0 430 mozilla::WritingMode mWritingMode;
michael@0 431 bool mZeroEffectiveSpanBox;
michael@0 432 bool mContainsFloat;
michael@0 433 bool mHasNonemptyContent;
michael@0 434
michael@0 435 nscoord mIStart;
michael@0 436 nscoord mICoord;
michael@0 437 nscoord mIEnd;
michael@0 438
michael@0 439 nscoord mBStartLeading, mBEndLeading;
michael@0 440 nscoord mLogicalBSize;
michael@0 441 nscoord mMinBCoord, mMaxBCoord;
michael@0 442 nscoord* mBaseline;
michael@0 443
michael@0 444 void AppendFrame(PerFrameData* pfd) {
michael@0 445 if (nullptr == mLastFrame) {
michael@0 446 mFirstFrame = pfd;
michael@0 447 }
michael@0 448 else {
michael@0 449 mLastFrame->mNext = pfd;
michael@0 450 pfd->mPrev = mLastFrame;
michael@0 451 }
michael@0 452 mLastFrame = pfd;
michael@0 453 }
michael@0 454 };
michael@0 455 PerSpanData* mSpanFreeList;
michael@0 456 PerSpanData* mRootSpan;
michael@0 457 PerSpanData* mCurrentSpan;
michael@0 458
michael@0 459 gfxBreakPriority mLastOptionalBreakPriority;
michael@0 460 int32_t mLastOptionalBreakContentOffset;
michael@0 461 int32_t mForceBreakContentOffset;
michael@0 462
michael@0 463 nscoord mMinLineBSize;
michael@0 464
michael@0 465 // The amount of text indent that we applied to this line, needed for
michael@0 466 // max-element-size calculation.
michael@0 467 nscoord mTextIndent;
michael@0 468
michael@0 469 // This state varies during the reflow of a line but is line
michael@0 470 // "global" state not span "local" state.
michael@0 471 int32_t mLineNumber;
michael@0 472 int32_t mTextJustificationNumSpaces;
michael@0 473 int32_t mTextJustificationNumLetters;
michael@0 474
michael@0 475 int32_t mTotalPlacedFrames;
michael@0 476
michael@0 477 nscoord mBStartEdge;
michael@0 478 nscoord mMaxStartBoxBSize;
michael@0 479 nscoord mMaxEndBoxBSize;
michael@0 480
michael@0 481 nscoord mInflationMinFontSize;
michael@0 482
michael@0 483 // Final computed line-bSize value after BlockDirAlignFrames for
michael@0 484 // the block has been called.
michael@0 485 nscoord mFinalLineBSize;
michael@0 486
michael@0 487 // Amount of trimmable whitespace width for the trailing text frame, if any
michael@0 488 nscoord mTrimmableWidth;
michael@0 489
michael@0 490 nscoord mContainerWidth;
michael@0 491
michael@0 492 bool mFirstLetterStyleOK : 1;
michael@0 493 bool mIsTopOfPage : 1;
michael@0 494 bool mImpactedByFloats : 1;
michael@0 495 bool mLastFloatWasLetterFrame : 1;
michael@0 496 bool mLineIsEmpty : 1;
michael@0 497 bool mLineEndsInBR : 1;
michael@0 498 bool mNeedBackup : 1;
michael@0 499 bool mInFirstLine : 1;
michael@0 500 bool mGotLineBox : 1;
michael@0 501 bool mInFirstLetter : 1;
michael@0 502 bool mHasBullet : 1;
michael@0 503 bool mDirtyNextLine : 1;
michael@0 504 bool mLineAtStart : 1;
michael@0 505
michael@0 506 int32_t mSpanDepth;
michael@0 507 #ifdef DEBUG
michael@0 508 int32_t mSpansAllocated, mSpansFreed;
michael@0 509 int32_t mFramesAllocated, mFramesFreed;
michael@0 510 #endif
michael@0 511 PLArenaPool mArena; // Per span and per frame data, 4 byte aligned
michael@0 512
michael@0 513 /**
michael@0 514 * Allocate a PerFrameData from the mArena pool. The allocation is infallible.
michael@0 515 */
michael@0 516 PerFrameData* NewPerFrameData(nsIFrame* aFrame);
michael@0 517
michael@0 518 /**
michael@0 519 * Allocate a PerSpanData from the mArena pool. The allocation is infallible.
michael@0 520 */
michael@0 521 PerSpanData* NewPerSpanData();
michael@0 522
michael@0 523 void FreeSpan(PerSpanData* psd);
michael@0 524
michael@0 525 bool InBlockContext() const {
michael@0 526 return mSpanDepth == 0;
michael@0 527 }
michael@0 528
michael@0 529 void PushFrame(nsIFrame* aFrame);
michael@0 530
michael@0 531 void AllowForStartMargin(PerFrameData* pfd,
michael@0 532 nsHTMLReflowState& aReflowState);
michael@0 533
michael@0 534 bool CanPlaceFrame(PerFrameData* pfd,
michael@0 535 bool aNotSafeToBreak,
michael@0 536 bool aFrameCanContinueTextRun,
michael@0 537 bool aCanRollBackBeforeFrame,
michael@0 538 nsHTMLReflowMetrics& aMetrics,
michael@0 539 nsReflowStatus& aStatus,
michael@0 540 bool* aOptionalBreakAfterFits);
michael@0 541
michael@0 542 void PlaceFrame(PerFrameData* pfd,
michael@0 543 nsHTMLReflowMetrics& aMetrics);
michael@0 544
michael@0 545 void BlockDirAlignFrames(PerSpanData* psd);
michael@0 546
michael@0 547 void PlaceStartEndFrames(PerSpanData* psd,
michael@0 548 nscoord aDistanceFromStart,
michael@0 549 nscoord aLineBSize);
michael@0 550
michael@0 551 void RelativePositionFrames(PerSpanData* psd, nsOverflowAreas& aOverflowAreas);
michael@0 552
michael@0 553 bool TrimTrailingWhiteSpaceIn(PerSpanData* psd, nscoord* aDeltaISize);
michael@0 554
michael@0 555 void ComputeJustificationWeights(PerSpanData* psd, int32_t* numSpaces, int32_t* numLetters);
michael@0 556
michael@0 557 struct FrameJustificationState {
michael@0 558 int32_t mTotalNumSpaces;
michael@0 559 int32_t mTotalNumLetters;
michael@0 560 nscoord mTotalWidthForSpaces;
michael@0 561 nscoord mTotalWidthForLetters;
michael@0 562 int32_t mNumSpacesProcessed;
michael@0 563 int32_t mNumLettersProcessed;
michael@0 564 nscoord mWidthForSpacesProcessed;
michael@0 565 nscoord mWidthForLettersProcessed;
michael@0 566 };
michael@0 567
michael@0 568 // Apply justification. The return value is the amount by which the width of
michael@0 569 // the span corresponding to aPSD got increased due to justification.
michael@0 570 nscoord ApplyFrameJustification(PerSpanData* aPSD,
michael@0 571 FrameJustificationState* aState);
michael@0 572
michael@0 573
michael@0 574 #ifdef DEBUG
michael@0 575 void DumpPerSpanData(PerSpanData* psd, int32_t aIndent);
michael@0 576 #endif
michael@0 577 };
michael@0 578
michael@0 579 #endif /* nsLineLayout_h___ */

mercurial