diff --git a/layout/generic/nsBlockFrame.cpp b/layout/generic/nsBlockFrame.cpp index 0797c0e8338..ed0f34161f8 100644 --- a/layout/generic/nsBlockFrame.cpp +++ b/layout/generic/nsBlockFrame.cpp @@ -728,7 +728,7 @@ nsBlockFrame::GetMinISize(nsRenderingContext *aRenderingContext) // XXX Bug NNNNNN Should probably handle percentage text-indent. data.line = &line; - data.lineContainer = curFrame; + data.SetLineContainer(curFrame); nsIFrame *kid = line->mFirstChild; for (int32_t i = 0, i_end = line->GetChildCount(); i != i_end; ++i, kid = kid->GetNextSibling()) { @@ -813,7 +813,7 @@ nsBlockFrame::GetPrefISize(nsRenderingContext *aRenderingContext) // XXX Bug NNNNNN Should probably handle percentage text-indent. data.line = &line; - data.lineContainer = curFrame; + data.SetLineContainer(curFrame); nsIFrame *kid = line->mFirstChild; for (int32_t i = 0, i_end = line->GetChildCount(); i != i_end; ++i, kid = kid->GetNextSibling()) { @@ -887,7 +887,7 @@ nsBlockFrame::GetPrefWidthTightBounds(nsRenderingContext* aRenderingContext, // XXX Bug NNNNNN Should probably handle percentage text-indent. data.line = &line; - data.lineContainer = curFrame; + data.SetLineContainer(curFrame); nsIFrame *kid = line->mFirstChild; for (int32_t i = 0, i_end = line->GetChildCount(); i != i_end; ++i, kid = kid->GetNextSibling()) { diff --git a/layout/generic/nsContainerFrame.cpp b/layout/generic/nsContainerFrame.cpp index 2dcba6521cd..2311c6c6834 100644 --- a/layout/generic/nsContainerFrame.cpp +++ b/layout/generic/nsContainerFrame.cpp @@ -850,7 +850,7 @@ nsContainerFrame::DoInlineIntrinsicISize(nsRenderingContext *aRenderingContext, } const nsLineList_iterator* savedLine = aData->line; - nsIFrame* const savedLineContainer = aData->lineContainer; + nsIFrame* const savedLineContainer = aData->LineContainer(); nsContainerFrame *lastInFlow; for (nsContainerFrame *nif = this; nif; @@ -870,13 +870,13 @@ nsContainerFrame::DoInlineIntrinsicISize(nsRenderingContext *aRenderingContext, // After we advance to our next-in-flow, the stored line and line container // may no longer be correct. Just forget them. aData->line = nullptr; - aData->lineContainer = nullptr; + aData->SetLineContainer(nullptr); lastInFlow = nif; } aData->line = savedLine; - aData->lineContainer = savedLineContainer; + aData->SetLineContainer(savedLineContainer); // This goes at the end no matter how things are broken and how // messy the bidi situations are, since per CSS2.1 section 8.6 diff --git a/layout/generic/nsFrame.cpp b/layout/generic/nsFrame.cpp index 0c462d9e37f..66006a5acd8 100644 --- a/layout/generic/nsFrame.cpp +++ b/layout/generic/nsFrame.cpp @@ -4115,12 +4115,10 @@ nsIFrame::InlinePrefISizeData::ForceBreak(nsRenderingContext *aRenderingContext) floats_cur_left = 0, floats_cur_right = 0; - WritingMode wm = lineContainer->GetWritingMode(); - for (uint32_t i = 0, i_end = floats.Length(); i != i_end; ++i) { const FloatInfo& floatInfo = floats[i]; const nsStyleDisplay *floatDisp = floatInfo.Frame()->StyleDisplay(); - uint8_t breakType = floatDisp->PhysicalBreakType(wm); + uint8_t breakType = floatDisp->PhysicalBreakType(lineContainerWM); if (breakType == NS_STYLE_CLEAR_LEFT || breakType == NS_STYLE_CLEAR_RIGHT || breakType == NS_STYLE_CLEAR_BOTH) { @@ -4137,7 +4135,7 @@ nsIFrame::InlinePrefISizeData::ForceBreak(nsRenderingContext *aRenderingContext) } } - uint8_t floatStyle = floatDisp->PhysicalFloats(wm); + uint8_t floatStyle = floatDisp->PhysicalFloats(lineContainerWM); nscoord& floats_cur = floatStyle == NS_STYLE_FLOAT_LEFT ? floats_cur_left : floats_cur_right; nscoord floatWidth = floatInfo.Width(); diff --git a/layout/generic/nsIFrame.h b/layout/generic/nsIFrame.h index 1419f6d4abc..3ccd1fdd171 100644 --- a/layout/generic/nsIFrame.h +++ b/layout/generic/nsIFrame.h @@ -1563,17 +1563,34 @@ public: , lineContainer(nullptr) , prevLines(0) , currentLine(0) - , skipWhitespace(true) , trailingWhitespace(0) + , skipWhitespace(true) {} // The line. This may be null if the inlines are not associated with // a block or if we just don't know the line. const nsLineList_iterator* line; - // The line container. + // The line container. Private, to ensure we always use SetLineContainer + // to update it (so that we have a chance to store the lineContainerWM). + // + // Note that nsContainerFrame::DoInlineIntrinsicISize will clear the + // |line| and |lineContainer| fields when following a next-in-flow link, + // so we must not assume these can always be dereferenced. + private: nsIFrame* lineContainer; + // Setter and getter for the lineContainer field: + public: + void SetLineContainer(nsIFrame* aLineContainer) + { + lineContainer = aLineContainer; + if (lineContainer) { + lineContainerWM = lineContainer->GetWritingMode(); + } + } + nsIFrame* LineContainer() const { return lineContainer; } + // The maximum intrinsic width for all previous lines. nscoord prevLines; @@ -1582,14 +1599,18 @@ public: // the caller should call |Break()|. nscoord currentLine; + // This contains the width of the trimmable whitespace at the end of + // |currentLine|; it is zero if there is no such whitespace. + nscoord trailingWhitespace; + // True if initial collapsable whitespace should be skipped. This // should be true at the beginning of a block, after hard breaks // and when the last text ended with whitespace. bool skipWhitespace; - // This contains the width of the trimmable whitespace at the end of - // |currentLine|; it is zero if there is no such whitespace. - nscoord trailingWhitespace; + // Writing mode of the line container (stored here so that we don't + // lose track of it if the lineContainer field is reset). + mozilla::WritingMode lineContainerWM; // Floats encountered in the lines. class FloatInfo { diff --git a/layout/generic/nsRubyBaseContainerFrame.cpp b/layout/generic/nsRubyBaseContainerFrame.cpp index be33805ab77..1187eaae682 100644 --- a/layout/generic/nsRubyBaseContainerFrame.cpp +++ b/layout/generic/nsRubyBaseContainerFrame.cpp @@ -148,13 +148,13 @@ CalculateColumnPrefISize(nsRenderingContext* aRenderingContext, if (frame) { nsIFrame::InlinePrefISizeData data; if (i == 0) { - data.lineContainer = aBaseISizeData->lineContainer; + data.SetLineContainer(aBaseISizeData->LineContainer()); data.skipWhitespace = aBaseISizeData->skipWhitespace; data.trailingWhitespace = aBaseISizeData->trailingWhitespace; } else { // The line container of ruby text frames is their parent, // ruby text container frame. - data.lineContainer = frame->GetParent(); + data.SetLineContainer(frame->GetParent()); } frame->AddInlinePrefISize(aRenderingContext, &data); MOZ_ASSERT(data.prevLines == 0, "Shouldn't have prev lines"); @@ -182,7 +182,7 @@ nsRubyBaseContainerFrame::AddInlineMinISize( // Since spans are not breakable internally, use our pref isize // directly if there is any span. nsIFrame::InlinePrefISizeData data; - data.lineContainer = aData->lineContainer; + data.SetLineContainer(aData->LineContainer()); data.skipWhitespace = aData->skipWhitespace; data.trailingWhitespace = aData->trailingWhitespace; AddInlinePrefISize(aRenderingContext, &data); diff --git a/layout/generic/nsTextFrame.cpp b/layout/generic/nsTextFrame.cpp index 0e847808dec..d60115904e7 100644 --- a/layout/generic/nsTextFrame.cpp +++ b/layout/generic/nsTextFrame.cpp @@ -7643,7 +7643,7 @@ nsTextFrame::AddInlineMinISizeForFlow(nsRenderingContext *aRenderingContext, uint32_t flowEndInTextRun; gfxContext* ctx = aRenderingContext->ThebesContext(); gfxSkipCharsIterator iter = - EnsureTextRun(aTextRunType, ctx, aData->lineContainer, + EnsureTextRun(aTextRunType, ctx, aData->LineContainer(), aData->line, &flowEndInTextRun); gfxTextRun *textRun = GetTextRun(aTextRunType); if (!textRun) @@ -7792,12 +7792,12 @@ nsTextFrame::AddInlineMinISize(nsRenderingContext *aRenderingContext, // lastTextRun will only be null for the first text frame. if (f == this || f->GetTextRun(trtype) != lastTextRun) { nsIFrame* lc; - if (aData->lineContainer && - aData->lineContainer != (lc = FindLineContainer(f))) { + if (aData->LineContainer() && + aData->LineContainer() != (lc = FindLineContainer(f))) { NS_ASSERTION(f != this, "wrong InlineMinISizeData container" " for first continuation"); aData->line = nullptr; - aData->lineContainer = lc; + aData->SetLineContainer(lc); } // This will process all the text frames that share the same textrun as f. @@ -7817,7 +7817,7 @@ nsTextFrame::AddInlinePrefISizeForFlow(nsRenderingContext *aRenderingContext, uint32_t flowEndInTextRun; gfxContext* ctx = aRenderingContext->ThebesContext(); gfxSkipCharsIterator iter = - EnsureTextRun(aTextRunType, ctx, aData->lineContainer, + EnsureTextRun(aTextRunType, ctx, aData->LineContainer(), aData->line, &flowEndInTextRun); gfxTextRun *textRun = GetTextRun(aTextRunType); if (!textRun) @@ -7930,12 +7930,12 @@ nsTextFrame::AddInlinePrefISize(nsRenderingContext *aRenderingContext, // lastTextRun will only be null for the first text frame. if (f == this || f->GetTextRun(trtype) != lastTextRun) { nsIFrame* lc; - if (aData->lineContainer && - aData->lineContainer != (lc = FindLineContainer(f))) { + if (aData->LineContainer() && + aData->LineContainer() != (lc = FindLineContainer(f))) { NS_ASSERTION(f != this, "wrong InlinePrefISizeData container" " for first continuation"); aData->line = nullptr; - aData->lineContainer = lc; + aData->SetLineContainer(lc); } // This will process all the text frames that share the same textrun as f.