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