author | Jonathan Kew <jkew@mozilla.com> |
Thu, 13 Nov 2014 08:58:02 +0000 | |
changeset 215471 | 3183bb0cb92caafed5778c190459e7c7947afb3b |
parent 215470 | 29519b0eac483941a063c825dfd06b5f8f1432f5 |
child 215472 | 5a6555e3ae8ca18f7ca55424945b525418c2d785 |
push id | 27817 |
push user | cbook@mozilla.com |
push date | Thu, 13 Nov 2014 15:21:11 +0000 |
treeherder | mozilla-central@ae27ae77e32f [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | smontagu |
bugs | 1094914 |
milestone | 36.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
layout/generic/nsLineLayout.cpp | file | annotate | diff | comparison | revisions | |
layout/generic/nsLineLayout.h | file | annotate | diff | comparison | revisions |
--- a/layout/generic/nsLineLayout.cpp +++ b/layout/generic/nsLineLayout.cpp @@ -603,18 +603,18 @@ nsLineLayout::NewPerFrameData(nsIFrame* pfd->mNext = nullptr; pfd->mPrev = nullptr; pfd->mFlags = 0; // all flags default to false pfd->mFrame = aFrame; WritingMode frameWM = aFrame->GetWritingMode(); WritingMode lineWM = mRootSpan->mWritingMode; pfd->mBounds = LogicalRect(lineWM); - pfd->mMargin = LogicalMargin(frameWM); - pfd->mBorderPadding = LogicalMargin(frameWM); + pfd->mMargin = LogicalMargin(lineWM); + pfd->mBorderPadding = LogicalMargin(lineWM); pfd->mOffsets = LogicalMargin(frameWM); pfd->mJustificationInfo = JustificationInfo(); pfd->mJustificationAssignment = JustificationAssignment(); #ifdef DEBUG pfd->mBlockDirAlign = 0xFF; mFramesAllocated++; @@ -804,19 +804,19 @@ nsLineLayout::ReflowFrame(nsIFrame* aFra nsHTMLReflowState& reflowState = *reflowStateHolder; reflowState.mLineLayout = this; reflowState.mFlags.mIsTopOfPage = mIsTopOfPage; if (reflowState.ComputedISize() == NS_UNCONSTRAINEDSIZE) { reflowState.AvailableISize() = availableSpaceOnLine; } WritingMode stateWM = reflowState.GetWritingMode(); pfd->mMargin = - reflowState.ComputedLogicalMargin().ConvertTo(frameWM, stateWM); + reflowState.ComputedLogicalMargin().ConvertTo(lineWM, stateWM); pfd->mBorderPadding = - reflowState.ComputedLogicalBorderPadding().ConvertTo(frameWM, stateWM); + reflowState.ComputedLogicalBorderPadding().ConvertTo(lineWM, stateWM); pfd->SetFlag(PFD_RELATIVEPOS, reflowState.mStyleDisplay->IsRelativelyPositionedStyle()); if (pfd->GetFlag(PFD_RELATIVEPOS)) { pfd->mOffsets = reflowState.ComputedLogicalOffsets().ConvertTo(frameWM, stateWM); } // Calculate whether the the frame should have a start margin and @@ -1081,43 +1081,45 @@ nsLineLayout::ReflowFrame(nsIFrame* aFra void nsLineLayout::AllowForStartMargin(PerFrameData* pfd, nsHTMLReflowState& aReflowState) { NS_ASSERTION(!aReflowState.IsFloating(), "How'd we get a floated inline frame? " "The frame ctor should've dealt with this."); - WritingMode frameWM = pfd->mFrame->GetWritingMode(); + WritingMode lineWM = mRootSpan->mWritingMode; // Only apply start-margin on the first-in flow for inline frames, // and make sure to not apply it to any inline other than the first // in an ib split. Note that the ib sibling (block-in-inline // sibling) annotations only live on the first continuation, but we // don't want to apply the start margin for later continuations // anyway. For box-decoration-break:clone we apply the start-margin // on all continuations. if ((pfd->mFrame->GetPrevContinuation() || pfd->mFrame->FrameIsNonFirstInIBSplit()) && aReflowState.mStyleBorder->mBoxDecorationBreak == NS_STYLE_BOX_DECORATION_BREAK_SLICE) { // Zero this out so that when we compute the max-element-width of // the frame we will properly avoid adding in the starting margin. - pfd->mMargin.IStart(frameWM) = 0; + pfd->mMargin.IStart(lineWM) = 0; } else { NS_WARN_IF_FALSE(NS_UNCONSTRAINEDSIZE != aReflowState.AvailableISize(), "have unconstrained inline-size; this should only result " "from very large sizes, not attempts at intrinsic " "inline-size calculation"); if (NS_UNCONSTRAINEDSIZE == aReflowState.ComputedISize()) { // For inline-ish and text-ish things (which don't compute widths // in the reflow state), adjust available inline-size to account for the // start margin. The end margin will be accounted for when we // finish flowing the frame. - aReflowState.AvailableISize() -= pfd->mMargin.IStart(frameWM); + WritingMode wm = aReflowState.GetWritingMode(); + aReflowState.AvailableISize() -= + pfd->mMargin.ConvertTo(wm, lineWM).IStart(wm); } } } nscoord nsLineLayout::GetCurrentFrameInlineDistanceFromBlock() { PerSpanData* psd; @@ -1146,17 +1148,16 @@ nsLineLayout::CanPlaceFrame(PerFrameData nsHTMLReflowMetrics& aMetrics, nsReflowStatus& aStatus, bool* aOptionalBreakAfterFits) { NS_PRECONDITION(pfd && pfd->mFrame, "bad args, null pointers for frame data"); *aOptionalBreakAfterFits = true; - WritingMode frameWM = pfd->mFrame->GetWritingMode(); WritingMode lineWM = mRootSpan->mWritingMode; /* * We want to only apply the end margin if we're the last continuation and * either not in an {ib} split or the last inline in it. In all other * cases we want to zero it out. That means zeroing it out if any of these * conditions hold: * 1) The frame is not complete (in this case it will get a next-in-flow) * 2) The frame is complete but has a non-fluid continuation on its @@ -1171,24 +1172,22 @@ nsLineLayout::CanPlaceFrame(PerFrameData * continuations (that are not letter frames). */ if ((NS_FRAME_IS_NOT_COMPLETE(aStatus) || pfd->mFrame->LastInFlow()->GetNextContinuation() || pfd->mFrame->FrameIsNonLastInIBSplit()) && !pfd->GetFlag(PFD_ISLETTERFRAME) && pfd->mFrame->StyleBorder()->mBoxDecorationBreak == NS_STYLE_BOX_DECORATION_BREAK_SLICE) { - pfd->mMargin.IEnd(frameWM) = 0; + pfd->mMargin.IEnd(lineWM) = 0; } - // Convert the frame's margins to the line's writing mode and apply - // the start margin to the frame bounds. - LogicalMargin usedMargins = pfd->mMargin.ConvertTo(lineWM, frameWM); - nscoord startMargin = usedMargins.IStart(lineWM); - nscoord endMargin = usedMargins.IEnd(lineWM); + // Apply the start margin to the frame bounds. + nscoord startMargin = pfd->mMargin.IStart(lineWM); + nscoord endMargin = pfd->mMargin.IEnd(lineWM); pfd->mBounds.IStart(lineWM) += startMargin; PerSpanData* psd = mCurrentSpan; if (psd->mNoWrap) { // When wrapping is off, everything fits. return true; } @@ -1305,29 +1304,28 @@ nsLineLayout::CanPlaceFrame(PerFrameData } /** * Place the frame. Update running counters. */ void nsLineLayout::PlaceFrame(PerFrameData* pfd, nsHTMLReflowMetrics& aMetrics) { - WritingMode frameWM = pfd->mFrame->GetWritingMode(); WritingMode lineWM = mRootSpan->mWritingMode; // Record ascent and update max-ascent and max-descent values if (aMetrics.BlockStartAscent() == nsHTMLReflowMetrics::ASK_FOR_BASELINE) { pfd->mAscent = pfd->mFrame->GetLogicalBaseline(lineWM); } else { pfd->mAscent = aMetrics.BlockStartAscent(); } // Advance to next inline coordinate mCurrentSpan->mICoord = pfd->mBounds.IEnd(lineWM) + - pfd->mMargin.ConvertTo(lineWM, frameWM).IEnd(lineWM); + pfd->mMargin.IEnd(lineWM); // Count the number of non-placeholder frames on the line... if (pfd->mFrame->GetType() == nsGkAtoms::placeholderFrame) { NS_ASSERTION(pfd->mBounds.ISize(lineWM) == 0 && pfd->mBounds.BSize(lineWM) == 0, "placeholders should have 0 width/height (checking " "placeholders were never counted by the old code in " "this function)"); @@ -1504,47 +1502,46 @@ nsLineLayout::PlaceTopBottomFrames(PerSp nscoord aDistanceFromStart, nscoord aLineBSize) { for (PerFrameData* pfd = psd->mFirstFrame; pfd; pfd = pfd->mNext) { PerSpanData* span = pfd->mSpan; #ifdef DEBUG NS_ASSERTION(0xFF != pfd->mBlockDirAlign, "umr"); #endif - WritingMode frameWM = pfd->mFrame->GetWritingMode(); WritingMode lineWM = mRootSpan->mWritingMode; nscoord containerWidth = ContainerWidthForSpan(psd); switch (pfd->mBlockDirAlign) { case VALIGN_TOP: if (span) { pfd->mBounds.BStart(lineWM) = -aDistanceFromStart - span->mMinBCoord; } else { pfd->mBounds.BStart(lineWM) = - -aDistanceFromStart + pfd->mMargin.ConvertTo(lineWM, frameWM).BStart(lineWM); + -aDistanceFromStart + pfd->mMargin.BStart(lineWM); } pfd->mFrame->SetRect(lineWM, pfd->mBounds, containerWidth); #ifdef NOISY_BLOCKDIR_ALIGN printf(" "); nsFrame::ListTag(stdout, pfd->mFrame); printf(": y=%d dTop=%d [bp.top=%d topLeading=%d]\n", pfd->mBounds.BStart(lineWM), aDistanceFromStart, - span ? pfd->mBorderPadding.ConvertTo(lineWM, frameWM).BStart(lineWM) : 0, + span ? pfd->mBorderPadding.BStart(lineWM) : 0, span ? span->mBStartLeading : 0); #endif break; case VALIGN_BOTTOM: if (span) { // Compute bottom leading pfd->mBounds.BStart(lineWM) = -aDistanceFromStart + aLineBSize - span->mMaxBCoord; } else { pfd->mBounds.BStart(lineWM) = -aDistanceFromStart + aLineBSize - - pfd->mMargin.ConvertTo(lineWM, frameWM).BEnd(lineWM) - pfd->mBounds.BSize(lineWM); + pfd->mMargin.BEnd(lineWM) - pfd->mBounds.BSize(lineWM); } pfd->mFrame->SetRect(lineWM, pfd->mBounds, containerWidth); #ifdef NOISY_BLOCKDIR_ALIGN printf(" "); nsFrame::ListTag(stdout, pfd->mFrame); printf(": y=%d\n", pfd->mBounds.BStart(lineWM)); #endif break; @@ -1593,17 +1590,16 @@ nsLineLayout::VerticalAlignFrames(PerSpa inflation); bool preMode = mStyleText->WhiteSpaceIsSignificant(); // See if the span is an empty continuation. It's an empty continuation iff: // - it has a prev-in-flow // - it has no next in flow // - it's zero sized - WritingMode frameWM = spanFramePFD->mFrame->GetWritingMode(); WritingMode lineWM = mRootSpan->mWritingMode; bool emptyContinuation = psd != mRootSpan && spanFrame->GetPrevInFlow() && !spanFrame->GetNextInFlow() && spanFramePFD->mBounds.IsZeroSize(); #ifdef NOISY_BLOCKDIR_ALIGN printf("[%sSpan]", (psd == mRootSpan)?"Root":""); nsFrame::ListTag(stdout, spanFrame); @@ -1611,24 +1607,24 @@ nsLineLayout::VerticalAlignFrames(PerSpa preMode ? "yes" : "no", mPresContext->CompatibilityMode() != eCompatibility_NavQuirks ? "yes" : "no", spanFramePFD->mBounds.ISize(lineWM), spanFramePFD->mBounds.BSize(lineWM), emptyContinuation ? "yes" : "no"); if (psd != mRootSpan) { WritingMode frameWM = spanFramePFD->mFrame->GetWritingMode(); printf(" bp=%d,%d,%d,%d margin=%d,%d,%d,%d", - spanFramePFD->mBorderPadding.Top(frameWM), - spanFramePFD->mBorderPadding.Right(frameWM), - spanFramePFD->mBorderPadding.Bottom(frameWM), - spanFramePFD->mBorderPadding.Left(frameWM), - spanFramePFD->mMargin.Top(frameWM), - spanFramePFD->mMargin.Right(frameWM), - spanFramePFD->mMargin.Bottom(frameWM), - spanFramePFD->mMargin.Left(frameWM)); + spanFramePFD->mBorderPadding.Top(lineWM), + spanFramePFD->mBorderPadding.Right(lineWM), + spanFramePFD->mBorderPadding.Bottom(lineWM), + spanFramePFD->mBorderPadding.Left(lineWM), + spanFramePFD->mMargin.Top(lineWM), + spanFramePFD->mMargin.Right(lineWM), + spanFramePFD->mMargin.Bottom(lineWM), + spanFramePFD->mMargin.Left(lineWM)); } printf("\n"); #endif // Compute the span's mZeroEffectiveSpanBox flag. What we are trying // to determine is how we should treat the span: should it act // "normally" according to css2 or should it effectively // "disappear". @@ -1720,17 +1716,17 @@ nsLineLayout::VerticalAlignFrames(PerSpa // compute the top leading. float inflation = GetInflationForBlockDirAlignment(spanFrame, mInflationMinFontSize); nscoord logicalBSize = nsHTMLReflowState:: CalcLineHeight(spanFrame->GetContent(), spanFrame->StyleContext(), mBlockReflowState->ComputedHeight(), inflation); nscoord contentBSize = spanFramePFD->mBounds.BSize(lineWM) - - spanFramePFD->mBorderPadding.ConvertTo(lineWM, frameWM).BStartEnd(lineWM); + spanFramePFD->mBorderPadding.BStartEnd(lineWM); // Special-case for a ::first-letter frame, set the line height to // the frame block size if the user has left line-height == normal if (spanFramePFD->GetFlag(PFD_ISLETTERFRAME) && !spanFrame->GetPrevInFlow() && spanFrame->StyleText()->mLineHeight.GetUnit() == eStyleUnit_Normal) { logicalBSize = spanFramePFD->mBounds.BSize(lineWM); } @@ -1753,45 +1749,44 @@ nsLineLayout::VerticalAlignFrames(PerSpa } else { // The initial values for the min and max block coord values are in the // span's coordinate space, and cover the logical block size of the span. // If there are child frames in this span that stick out of this area // then the minBCoord and maxBCoord are updated by the amount of logical // blockSize that is outside this range. - minBCoord = spanFramePFD->mBorderPadding.ConvertTo(lineWM, frameWM).BStart(lineWM) - + minBCoord = spanFramePFD->mBorderPadding.BStart(lineWM) - psd->mBStartLeading; maxBCoord = minBCoord + psd->mLogicalBSize; } // This is the distance from the top edge of the parents visual // box to the baseline. The span already computed this for us, // so just use it. *psd->mBaseline = baselineBCoord = spanFramePFD->mAscent; #ifdef NOISY_BLOCKDIR_ALIGN printf("[%sSpan]", (psd == mRootSpan)?"Root":""); nsFrame::ListTag(stdout, spanFrame); printf(": baseLine=%d logicalBSize=%d topLeading=%d h=%d bp=%d,%d zeroEffectiveSpanBox=%s\n", baselineBCoord, psd->mLogicalBSize, psd->mBStartLeading, spanFramePFD->mBounds.BSize(lineWM), - spanFramePFD->mBorderPadding.Top(frameWM), - spanFramePFD->mBorderPadding.Bottom(frameWM), + spanFramePFD->mBorderPadding.Top(lineWM), + spanFramePFD->mBorderPadding.Bottom(lineWM), zeroEffectiveSpanBox ? "yes" : "no"); #endif } nscoord maxStartBoxBSize = 0; nscoord maxEndBoxBSize = 0; PerFrameData* pfd = psd->mFirstFrame; while (nullptr != pfd) { nsIFrame* frame = pfd->mFrame; - WritingMode frameWM = frame->GetWritingMode(); // sanity check (see bug 105168, non-reproducible crashes from null frame) NS_ASSERTION(frame, "null frame in PerFrameData - something is very very bad"); if (!frame) { return; } // Compute the logical block size of the frame @@ -1801,17 +1796,17 @@ nsLineLayout::VerticalAlignFrames(PerSpa // For span frames the logical-block-size and start-leading were // pre-computed when the span was reflowed. logicalBSize = frameSpan->mLogicalBSize; } else { // For other elements the logical block size is the same as the // frame's block size plus its margins. logicalBSize = pfd->mBounds.BSize(lineWM) + - pfd->mMargin.ConvertTo(lineWM, frameWM).BStartEnd(lineWM); + pfd->mMargin.BStartEnd(lineWM); if (logicalBSize < 0 && mPresContext->CompatibilityMode() == eCompatibility_NavQuirks) { pfd->mAscent -= logicalBSize; logicalBSize = 0; } } // Get vertical-align property ("vertical-align" is the CSS name for @@ -1909,71 +1904,71 @@ nsLineLayout::VerticalAlignFrames(PerSpa nscoord parentXHeight = fm->XHeight(); if (frameSpan) { pfd->mBounds.BStart(lineWM) = baselineBCoord - (parentXHeight + pfd->mBounds.BSize(lineWM))/2; } else { pfd->mBounds.BStart(lineWM) = baselineBCoord - (parentXHeight + logicalBSize)/2 + - pfd->mMargin.ConvertTo(lineWM, frameWM).BStart(lineWM); + pfd->mMargin.BStart(lineWM); } pfd->mBlockDirAlign = VALIGN_OTHER; break; } case NS_STYLE_VERTICAL_ALIGN_TEXT_TOP: { // The top of the logical box is aligned with the top of // the parent element's text. // XXX For vertical text we will need a new API to get the logical // max-ascent here nscoord parentAscent = fm->MaxAscent(); if (frameSpan) { pfd->mBounds.BStart(lineWM) = baselineBCoord - parentAscent - - pfd->mBorderPadding.ConvertTo(lineWM, frameWM).BStart(lineWM) + frameSpan->mBStartLeading; + pfd->mBorderPadding.BStart(lineWM) + frameSpan->mBStartLeading; } else { pfd->mBounds.BStart(lineWM) = baselineBCoord - parentAscent + - pfd->mMargin.ConvertTo(lineWM, frameWM).BStart(lineWM); + pfd->mMargin.BStart(lineWM); } pfd->mBlockDirAlign = VALIGN_OTHER; break; } case NS_STYLE_VERTICAL_ALIGN_TEXT_BOTTOM: { // The bottom of the logical box is aligned with the // bottom of the parent elements text. nscoord parentDescent = fm->MaxDescent(); if (frameSpan) { pfd->mBounds.BStart(lineWM) = baselineBCoord + parentDescent - pfd->mBounds.BSize(lineWM) + - pfd->mBorderPadding.ConvertTo(lineWM, frameWM).BEnd(lineWM) - + pfd->mBorderPadding.BEnd(lineWM) - frameSpan->mBEndLeading; } else { pfd->mBounds.BStart(lineWM) = baselineBCoord + parentDescent - pfd->mBounds.BSize(lineWM) - - pfd->mMargin.ConvertTo(lineWM, frameWM).BEnd(lineWM); + pfd->mMargin.BEnd(lineWM); } pfd->mBlockDirAlign = VALIGN_OTHER; break; } case NS_STYLE_VERTICAL_ALIGN_MIDDLE_WITH_BASELINE: { // Align the midpoint of the frame with the baseline of the parent. if (frameSpan) { pfd->mBounds.BStart(lineWM) = baselineBCoord - pfd->mBounds.BSize(lineWM)/2; } else { pfd->mBounds.BStart(lineWM) = baselineBCoord - logicalBSize/2 + - pfd->mMargin.ConvertTo(lineWM, frameWM).BStart(lineWM); + pfd->mMargin.BStart(lineWM); } pfd->mBlockDirAlign = VALIGN_OTHER; break; } } } else { // We have either a coord, a percent, or a calc(). nscoord pctBasis = 0; @@ -2029,17 +2024,17 @@ nsLineLayout::VerticalAlignFrames(PerSpa // For spans that were are now placing, use their position // plus their already computed min-Y and max-Y values for // computing blockStart and blockEnd. blockStart = pfd->mBounds.BStart(lineWM) + frameSpan->mMinBCoord; blockEnd = pfd->mBounds.BStart(lineWM) + frameSpan->mMaxBCoord; } else { blockStart = pfd->mBounds.BStart(lineWM) - - pfd->mMargin.ConvertTo(lineWM, frameWM).BStart(lineWM); + pfd->mMargin.BStart(lineWM); blockEnd = blockStart + logicalBSize; } if (!preMode && mPresContext->CompatibilityMode() != eCompatibility_FullStandards && !logicalBSize) { // Check if it's a BR frame that is not alone on its line (it // is given a block size of zero to indicate this), and if so reset // blockStart and blockEnd so that BR frames don't influence the line. @@ -2048,18 +2043,18 @@ nsLineLayout::VerticalAlignFrames(PerSpa blockEnd = BLOCKDIR_ALIGN_FRAMES_NO_MAXIMUM; } } if (blockStart < minBCoord) minBCoord = blockStart; if (blockEnd > maxBCoord) maxBCoord = blockEnd; #ifdef NOISY_BLOCKDIR_ALIGN printf(" [frame]raw: a=%d h=%d bp=%d,%d logical: h=%d leading=%d y=%d minBCoord=%d maxBCoord=%d\n", pfd->mAscent, pfd->mBounds.BSize(lineWM), - pfd->mBorderPadding.Top(frameWM), - pfd->mBorderPadding.Bottom(frameWM), + pfd->mBorderPadding.Top(lineWM), + pfd->mBorderPadding.Bottom(lineWM), logicalBSize, frameSpan ? frameSpan->mBStartLeading : 0, pfd->mBounds.BStart(lineWM), minBCoord, maxBCoord); #endif } if (psd != mRootSpan) { frame->SetRect(lineWM, pfd->mBounds, ContainerWidthForSpan(psd)); } @@ -2140,18 +2135,18 @@ nsLineLayout::VerticalAlignFrames(PerSpa if ((psd != mRootSpan) && (psd->mZeroEffectiveSpanBox)) { #ifdef NOISY_BLOCKDIR_ALIGN printf(" [span]adjusting for zeroEffectiveSpanBox\n"); printf(" Original: minBCoord=%d, maxBCoord=%d, bSize=%d, ascent=%d, logicalBSize=%d, topLeading=%d, bottomLeading=%d\n", minBCoord, maxBCoord, spanFramePFD->mBounds.BSize(frameWM), spanFramePFD->mAscent, psd->mLogicalBSize, psd->mBStartLeading, psd->mBEndLeading); #endif - nscoord goodMinBCoord = spanFramePFD->mBorderPadding.ConvertTo(lineWM, frameWM).BStart(lineWM) - - psd->mBStartLeading; + nscoord goodMinBCoord = + spanFramePFD->mBorderPadding.BStart(lineWM) - psd->mBStartLeading; nscoord goodMaxBCoord = goodMinBCoord + psd->mLogicalBSize; // For cases like the one in bug 714519 (text-decoration placement // or making nsLineLayout::IsZeroBSize() handle // vertical-align:top/bottom on a descendant of the line that's not // a child of it), we want to treat elements that are // vertical-align: top or bottom somewhat like children for the // purposes of this quirk. To some extent, this is guessing, since
--- a/layout/generic/nsLineLayout.h +++ b/layout/generic/nsLineLayout.h @@ -380,19 +380,19 @@ protected: nscoord mAscent; // note that mBounds is a logical rect in the *line*'s writing mode. // When setting frame coordinates, we have to convert to the frame's // writing mode mozilla::LogicalRect mBounds; nsOverflowAreas mOverflowAreas; // From reflow-state - mozilla::LogicalMargin mMargin; - mozilla::LogicalMargin mBorderPadding; - mozilla::LogicalMargin mOffsets; + mozilla::LogicalMargin mMargin; // in *line* writing mode + mozilla::LogicalMargin mBorderPadding; // in *line* writing mode + mozilla::LogicalMargin mOffsets; // in *frame* writing mode // state for text justification mozilla::JustificationInfo mJustificationInfo; mozilla::JustificationAssignment mJustificationAssignment; // PerFrameData flags #define PFD_RELATIVEPOS 0x00000001 #define PFD_ISTEXTFRAME 0x00000002