зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1322843 part 2 - Conditionally keep some floats in InlinePrefISizeData::ForceBreak. r=dbaron
This patch makes ForceBreak() partially clear floats according to the break type of the coming block. MozReview-Commit-ID: 71Gl9lBoTJ5 --HG-- extra : rebase_source : 5ca01565f607241df0c63a7cd64c35ac7ff7648f
This commit is contained in:
Родитель
0f9ff65fce
Коммит
0fe4f86e06
|
@ -838,9 +838,14 @@ nsBlockFrame::GetPrefISize(nsRenderingContext *aRenderingContext)
|
|||
AutoNoisyIndenter lineindent(gNoisyIntrinsic);
|
||||
#endif
|
||||
if (line->IsBlock()) {
|
||||
StyleClear breakType;
|
||||
if (!data.mLineIsEmpty || BlockCanIntersectFloats(line->mFirstChild)) {
|
||||
data.ForceBreak();
|
||||
breakType = StyleClear::Both;
|
||||
} else {
|
||||
breakType = line->mFirstChild->
|
||||
StyleDisplay()->PhysicalBreakType(data.mLineContainerWM);
|
||||
}
|
||||
data.ForceBreak(breakType);
|
||||
data.mCurrentLine = nsLayoutUtils::IntrinsicForContainer(aRenderingContext,
|
||||
line->mFirstChild, nsLayoutUtils::PREF_ISIZE);
|
||||
data.ForceBreak();
|
||||
|
|
|
@ -4512,9 +4512,17 @@ nsIFrame::InlineMinISizeData::OptionallyBreak(nscoord aHyphenWidth)
|
|||
}
|
||||
|
||||
void
|
||||
nsIFrame::InlinePrefISizeData::ForceBreak()
|
||||
nsIFrame::InlinePrefISizeData::ForceBreak(StyleClear aBreakType)
|
||||
{
|
||||
if (mFloats.Length() != 0) {
|
||||
MOZ_ASSERT(aBreakType == StyleClear::None ||
|
||||
aBreakType == StyleClear::Both ||
|
||||
aBreakType == StyleClear::Left ||
|
||||
aBreakType == StyleClear::Right,
|
||||
"Must be a physical break type");
|
||||
|
||||
// If this force break is not clearing any float, we can leave all the
|
||||
// floats to the next force break.
|
||||
if (mFloats.Length() != 0 && aBreakType != StyleClear::None) {
|
||||
// preferred widths accumulated for floats that have already
|
||||
// been cleared past
|
||||
nscoord floats_done = 0,
|
||||
|
@ -4522,11 +4530,12 @@ nsIFrame::InlinePrefISizeData::ForceBreak()
|
|||
// been cleared past
|
||||
floats_cur_left = 0,
|
||||
floats_cur_right = 0;
|
||||
const WritingMode wm = mLineContainerWM;
|
||||
|
||||
for (uint32_t i = 0, i_end = mFloats.Length(); i != i_end; ++i) {
|
||||
const FloatInfo& floatInfo = mFloats[i];
|
||||
const nsStyleDisplay* floatDisp = floatInfo.Frame()->StyleDisplay();
|
||||
StyleClear breakType = floatDisp->PhysicalBreakType(mLineContainerWM);
|
||||
StyleClear breakType = floatDisp->PhysicalBreakType(wm);
|
||||
if (breakType == StyleClear::Left ||
|
||||
breakType == StyleClear::Right ||
|
||||
breakType == StyleClear::Both) {
|
||||
|
@ -4543,7 +4552,7 @@ nsIFrame::InlinePrefISizeData::ForceBreak()
|
|||
}
|
||||
}
|
||||
|
||||
StyleFloat floatStyle = floatDisp->PhysicalFloats(mLineContainerWM);
|
||||
StyleFloat floatStyle = floatDisp->PhysicalFloats(wm);
|
||||
nscoord& floats_cur =
|
||||
floatStyle == StyleFloat::Left ? floats_cur_left : floats_cur_right;
|
||||
nscoord floatWidth = floatInfo.Width();
|
||||
|
@ -4560,7 +4569,44 @@ nsIFrame::InlinePrefISizeData::ForceBreak()
|
|||
|
||||
mCurrentLine = NSCoordSaturatingAdd(mCurrentLine, floats_done);
|
||||
|
||||
if (aBreakType == StyleClear::Both) {
|
||||
mFloats.Clear();
|
||||
} else {
|
||||
// If the break type does not clear all floats, it means there may
|
||||
// be some floats whose isize should contribute to the intrinsic
|
||||
// isize of the next line. The code here scans the current mFloats
|
||||
// and keeps floats which are not cleared by this break. Note that
|
||||
// floats may be cleared directly or indirectly. See below.
|
||||
nsTArray<FloatInfo> newFloats;
|
||||
MOZ_ASSERT(aBreakType == StyleClear::Left ||
|
||||
aBreakType == StyleClear::Right,
|
||||
"Other values should have been handled in other branches");
|
||||
StyleFloat clearFloatType =
|
||||
aBreakType == StyleClear::Left ? StyleFloat::Left : StyleFloat::Right;
|
||||
// Iterate the array in reverse so that we can stop when there are
|
||||
// no longer any floats we need to keep. See below.
|
||||
for (FloatInfo& floatInfo : Reversed(mFloats)) {
|
||||
const nsStyleDisplay* floatDisp = floatInfo.Frame()->StyleDisplay();
|
||||
if (floatDisp->PhysicalFloats(wm) != clearFloatType) {
|
||||
newFloats.AppendElement(floatInfo);
|
||||
} else {
|
||||
// This is a float on the side that this break directly clears
|
||||
// which means we're not keeping it in mFloats. However, if
|
||||
// this float clears floats on the opposite side (via a value
|
||||
// of either 'both' or one of 'left'/'right'), any remaining
|
||||
// (earlier) floats on that side would be indirectly cleared
|
||||
// as well. Thus, we should break out of this loop and stop
|
||||
// considering earlier floats to be kept in mFloats.
|
||||
StyleClear floatBreakType = floatDisp->PhysicalBreakType(wm);
|
||||
if (floatBreakType != aBreakType &&
|
||||
floatBreakType != StyleClear::None) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
newFloats.Reverse();
|
||||
mFloats = Move(newFloats);
|
||||
}
|
||||
}
|
||||
|
||||
mCurrentLine =
|
||||
|
|
|
@ -2020,11 +2020,29 @@ public:
|
|||
};
|
||||
|
||||
struct InlinePrefISizeData : public InlineIntrinsicISizeData {
|
||||
typedef mozilla::StyleClear StyleClear;
|
||||
|
||||
InlinePrefISizeData()
|
||||
: mLineIsEmpty(true)
|
||||
{}
|
||||
|
||||
void ForceBreak();
|
||||
/**
|
||||
* Finish the current line and start a new line.
|
||||
*
|
||||
* @param aBreakType controls whether isize of floats are considered
|
||||
* and what floats are kept for the next line:
|
||||
* * |None| skips handling floats, which means no floats are
|
||||
* removed, and isizes of floats are not considered either.
|
||||
* * |Both| takes floats into consideration when computing isize
|
||||
* of the current line, and removes all floats after that.
|
||||
* * |Left| and |Right| do the same as |Both| except that they only
|
||||
* remove floats on the given side, and any floats on the other
|
||||
* side that are prior to a float on the given side that has a
|
||||
* 'clear' property that clears them.
|
||||
* All other values of StyleClear must be converted to the four
|
||||
* physical values above for this function.
|
||||
*/
|
||||
void ForceBreak(StyleClear aBreakType = StyleClear::Both);
|
||||
|
||||
// The default implementation for nsIFrame::AddInlinePrefISize.
|
||||
void DefaultAddInlinePrefISize(nscoord aISize);
|
||||
|
|
Загрузка…
Ссылка в новой задаче