author | Mats Palmgren <mats@mozilla.com> |
Thu, 14 Apr 2016 01:32:12 +0200 | |
changeset 293132 | 8ba874ed8bf874a6f810065df09ad552137be8d3 |
parent 293131 | 5f8bcba5c5e00491fe020177470be81543255313 |
child 293133 | 812c15b34793ac1c0bdd5560af46461f1b5ac5a4 |
push id | 30175 |
push user | cbook@mozilla.com |
push date | Thu, 14 Apr 2016 09:38:40 +0000 |
treeherder | mozilla-central@91115264629d [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | dholbert |
bugs | 645647 |
milestone | 48.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
|
--- a/layout/generic/nsBulletFrame.cpp +++ b/layout/generic/nsBulletFrame.cpp @@ -676,16 +676,52 @@ nsBulletFrame::GetPrefISize(nsRenderingC nsHTMLReflowMetrics metrics(wm); DISPLAY_PREF_WIDTH(this, metrics.ISize(wm)); LogicalMargin padding(wm); GetDesiredSize(PresContext(), aRenderingContext, metrics, 1.0f, &padding); metrics.ISize(wm) += padding.IStartEnd(wm); return metrics.ISize(wm); } +// If a bullet has zero size and is "ignorable" from its styling, we behave +// as if it doesn't exist, from a line-breaking/isize-computation perspective. +// Otherwise, we use the default implementation, same as nsFrame. +static inline bool +IsIgnoreable(const nsIFrame* aFrame, nscoord aISize) +{ + if (aISize != nscoord(0)) { + return false; + } + auto listStyle = aFrame->StyleList(); + return listStyle->GetCounterStyle()->IsNone() && + !listStyle->GetListStyleImage(); +} + +/* virtual */ void +nsBulletFrame::AddInlineMinISize(nsRenderingContext* aRenderingContext, + nsIFrame::InlineMinISizeData* aData) +{ + nscoord isize = nsLayoutUtils::IntrinsicForContainer(aRenderingContext, + this, nsLayoutUtils::MIN_ISIZE); + if (MOZ_LIKELY(!::IsIgnoreable(this, isize))) { + aData->DefaultAddInlineMinISize(this, isize); + } +} + +/* virtual */ void +nsBulletFrame::AddInlinePrefISize(nsRenderingContext* aRenderingContext, + nsIFrame::InlinePrefISizeData* aData) +{ + nscoord isize = nsLayoutUtils::IntrinsicForContainer(aRenderingContext, + this, nsLayoutUtils::PREF_ISIZE); + if (MOZ_LIKELY(!::IsIgnoreable(this, isize))) { + aData->DefaultAddInlinePrefISize(isize); + } +} + NS_IMETHODIMP nsBulletFrame::Notify(imgIRequest *aRequest, int32_t aType, const nsIntRect* aData) { if (aType == imgINotificationObserver::SIZE_AVAILABLE) { nsCOMPtr<imgIContainer> image; aRequest->GetImage(getter_AddRefs(image)); return OnSizeAvailable(aRequest, image); }
--- a/layout/generic/nsBulletFrame.h +++ b/layout/generic/nsBulletFrame.h @@ -71,23 +71,26 @@ public: const nsRect& aDirtyRect, const nsDisplayListSet& aLists) override; virtual nsIAtom* GetType() const override; virtual void DidSetStyleContext(nsStyleContext* aOldStyleContext) override; #ifdef DEBUG_FRAME_DUMP virtual nsresult GetFrameName(nsAString& aResult) const override; #endif - // nsIHTMLReflow virtual void Reflow(nsPresContext* aPresContext, nsHTMLReflowMetrics& aMetrics, const nsHTMLReflowState& aReflowState, nsReflowStatus& aStatus) override; virtual nscoord GetMinISize(nsRenderingContext *aRenderingContext) override; virtual nscoord GetPrefISize(nsRenderingContext *aRenderingContext) override; + void AddInlineMinISize(nsRenderingContext* aRenderingContext, + nsIFrame::InlineMinISizeData* aData) override; + void AddInlinePrefISize(nsRenderingContext* aRenderingContext, + nsIFrame::InlinePrefISizeData* aData) override; // nsBulletFrame int32_t SetListItemOrdinal(int32_t aNextOrdinal, bool* aChanged, int32_t aIncrement); /* get list item text, with prefix & suffix */ void GetListItemText(nsAString& aResult);
--- a/layout/generic/nsFrame.cpp +++ b/layout/generic/nsFrame.cpp @@ -4260,48 +4260,63 @@ nsFrame::GetMinISize(nsRenderingContext nsFrame::GetPrefISize(nsRenderingContext *aRenderingContext) { nscoord result = 0; DISPLAY_PREF_WIDTH(this, result); return result; } /* virtual */ void -nsFrame::AddInlineMinISize(nsRenderingContext *aRenderingContext, - nsIFrame::InlineMinISizeData *aData) -{ - NS_ASSERTION(GetParent(), "Must have a parent if we get here!"); - nsIFrame* parent = GetParent(); - bool canBreak = !CanContinueTextRun() && - !parent->StyleContext()->ShouldSuppressLineBreak() && - parent->StyleText()->WhiteSpaceCanWrap(parent); - - if (canBreak) { - aData->OptionallyBreak(); - } - aData->trailingWhitespace = 0; - aData->skipWhitespace = false; - aData->trailingTextFrame = nullptr; - aData->currentLine += nsLayoutUtils::IntrinsicForContainer(aRenderingContext, - this, nsLayoutUtils::MIN_ISIZE); - aData->atStartOfLine = false; - if (canBreak) { - aData->OptionallyBreak(); - } +nsFrame::AddInlineMinISize(nsRenderingContext* aRenderingContext, + nsIFrame::InlineMinISizeData* aData) +{ + nscoord isize = nsLayoutUtils::IntrinsicForContainer(aRenderingContext, + this, nsLayoutUtils::MIN_ISIZE); + aData->DefaultAddInlineMinISize(this, isize); } /* virtual */ void -nsFrame::AddInlinePrefISize(nsRenderingContext *aRenderingContext, - nsIFrame::InlinePrefISizeData *aData) -{ - aData->trailingWhitespace = 0; - aData->skipWhitespace = false; - nscoord myPref = nsLayoutUtils::IntrinsicForContainer(aRenderingContext, - this, nsLayoutUtils::PREF_ISIZE); - aData->currentLine = NSCoordSaturatingAdd(aData->currentLine, myPref); +nsFrame::AddInlinePrefISize(nsRenderingContext* aRenderingContext, + nsIFrame::InlinePrefISizeData* aData) +{ + nscoord isize = nsLayoutUtils::IntrinsicForContainer(aRenderingContext, + this, nsLayoutUtils::PREF_ISIZE); + aData->DefaultAddInlinePrefISize(isize); +} + +void +nsIFrame::InlineMinISizeData::DefaultAddInlineMinISize(nsIFrame* aFrame, + nscoord aISize, + bool aAllowBreak) +{ + auto parent = aFrame->GetParent(); + MOZ_ASSERT(parent, "Must have a parent if we get here!"); + const bool mayBreak = aAllowBreak && + !aFrame->CanContinueTextRun() && + !parent->StyleContext()->ShouldSuppressLineBreak() && + parent->StyleText()->WhiteSpaceCanWrap(parent); + if (mayBreak) { + OptionallyBreak(); + } + trailingWhitespace = 0; + skipWhitespace = false; + trailingTextFrame = nullptr; + currentLine += aISize; + atStartOfLine = false; + if (mayBreak) { + OptionallyBreak(); + } +} + +void +nsIFrame::InlinePrefISizeData::DefaultAddInlinePrefISize(nscoord aISize) +{ + currentLine = NSCoordSaturatingAdd(currentLine, aISize); + trailingWhitespace = 0; + skipWhitespace = false; } void nsIFrame::InlineMinISizeData::ForceBreak() { currentLine -= trailingWhitespace; prevLines = std::max(prevLines, currentLine); currentLine = trailingWhitespace = 0;
--- a/layout/generic/nsIFrame.h +++ b/layout/generic/nsIFrame.h @@ -1751,16 +1751,21 @@ public: }; struct InlineMinISizeData : public InlineIntrinsicISizeData { InlineMinISizeData() : trailingTextFrame(nullptr) , atStartOfLine(true) {} + // The default implementation for nsIFrame::AddInlineMinISize. + void DefaultAddInlineMinISize(nsIFrame* aFrame, + nscoord aISize, + bool aAllowBreak = true); + // We need to distinguish forced and optional breaks for cases where the // current line total is negative. When it is, we need to ignore // optional breaks to prevent min-width from ending up bigger than // pref-width. void ForceBreak(); // If the break here is actually taken, aHyphenWidth must be added to the // width of the current line. @@ -1774,16 +1779,19 @@ public: // Whether we're currently at the start of the line. If we are, we // can't break (for example, between the text-indent and the first // word). bool atStartOfLine; }; struct InlinePrefISizeData : public InlineIntrinsicISizeData { void ForceBreak(); + + // The default implementation for nsIFrame::AddInlinePrefISize. + void DefaultAddInlinePrefISize(nscoord aISize); }; /** * Add the intrinsic minimum width of a frame in a way suitable for * use in inline layout to an |InlineIntrinsicISizeData| object that * represents the intrinsic width information of all the previous * frames in the inline layout region. *
--- a/layout/generic/nsImageFrame.cpp +++ b/layout/generic/nsImageFrame.cpp @@ -2391,34 +2391,16 @@ IsInAutoWidthTableCellForQuirk(nsIFrame nsFrame *grandAncestor = static_cast<nsFrame*>(ancestor->GetParent()); return grandAncestor && grandAncestor->StylePosition()->mWidth.GetUnit() == eStyleUnit_Auto; } return false; } /* virtual */ void -nsImageFrame::AddInlineMinISize(nsRenderingContext *aRenderingContext, - nsIFrame::InlineMinISizeData *aData) +nsImageFrame::AddInlineMinISize(nsRenderingContext* aRenderingContext, + nsIFrame::InlineMinISizeData* aData) { - - NS_ASSERTION(GetParent(), "Must have a parent if we get here!"); - - nsIFrame* parent = GetParent(); - bool canBreak = - !CanContinueTextRun() && - parent->StyleText()->WhiteSpaceCanWrap(parent) && - !IsInAutoWidthTableCellForQuirk(this); - - if (canBreak) { - aData->OptionallyBreak(); - } - aData->trailingWhitespace = 0; - aData->skipWhitespace = false; - aData->trailingTextFrame = nullptr; - aData->currentLine += nsLayoutUtils::IntrinsicForContainer(aRenderingContext, - this, nsLayoutUtils::MIN_ISIZE); - aData->atStartOfLine = false; - - if (canBreak) { - aData->OptionallyBreak(); - } + nscoord isize = nsLayoutUtils::IntrinsicForContainer(aRenderingContext, + this, nsLayoutUtils::MIN_ISIZE); + bool canBreak = !IsInAutoWidthTableCellForQuirk(this); + aData->DefaultAddInlineMinISize(this, isize, canBreak); }