Bug 921876 - Stop #including nsIFrame.h in nsLayoutUtils.h; r=roc

This patch does the following:
* Move nsIFrame::IntrinsicSize to mozilla::IntrinsicSize so that it can
  be forward-declared.
* Move a number of templated inline nsLayoutUtils methods to nsIFrame.
* Use mozilla::layout::FrameChildListID instead of the
  nsIFrame::ChildListID typedef in nsLayoutUtils.h.
* Move nsReflowFrameRunnable to its only user, nsProgressMeterFrame.cpp.
* Make a number of functions requiring nsIFrame.h out-of-line.
* Remove the nsIFrame.h #include from nsLayoutUtils.h and add it to the
  places which require it implicitly.
This commit is contained in:
Ehsan Akhgari
2013-09-30 17:26:04 -04:00
parent 9a7ceadb0e
commit 6cf84bf2d9
33 changed files with 382 additions and 327 deletions

View File

@@ -20,6 +20,8 @@
#include "gfxContext.h"
#include "nsLayoutUtils.h"
#include "nsContentUtils.h"
#include "nsCSSValue.h"
#include "nsRuleNode.h"
using namespace mozilla::ipc;

View File

@@ -22,6 +22,7 @@
#include "nsIObserver.h"
#include "GLContextProvider.h"
#include "gfxImageSurface.h"
#include "mozilla/LinkedList.h"
#include "mozilla/CheckedInt.h"

View File

@@ -9,6 +9,7 @@
#include "mozilla/dom/TouchBinding.h"
#include "nsContentUtils.h"
#include "nsDOMTouchEvent.h"
#include "nsIContent.h"
namespace mozilla {
namespace dom {

View File

@@ -14,6 +14,8 @@
#include "nsPresContext.h"
#include "nsDeviceContext.h"
class nsINode;
class nsDOMUIEvent : public nsDOMEvent,
public nsIDOMUIEvent
{

View File

@@ -11,6 +11,8 @@
#include "nsCxPusher.h"
#include "nsError.h"
#include <new>
#include "nsIContent.h"
#include "nsIDocument.h"
#include "nsINode.h"
#include "nsPIDOMWindow.h"
#include "nsDOMTouchEvent.h"

View File

@@ -37,6 +37,7 @@
#include "nsIObserverService.h"
#include "nsIObjectFrame.h"
#include "nsBindingManager.h"
#include "nsStyleCoord.h"
#include "mozilla/ContentEvents.h"
#include "mozilla/dom/Element.h"

View File

@@ -6,6 +6,7 @@
#include "mozilla/Hal.h"
#include "nsScreen.h"
#include "nsIDocShell.h"
#include "nsIDocument.h"
#include "nsPresContext.h"
#include "nsCOMPtr.h"
#include "nsIDocShellTreeItem.h"

View File

@@ -526,7 +526,7 @@ VectorImage::GetIntrinsicSize(nsSize* aSize)
return NS_ERROR_FAILURE;
*aSize = nsSize(-1, -1);
nsIFrame::IntrinsicSize rfSize = rootFrame->GetIntrinsicSize();
IntrinsicSize rfSize = rootFrame->GetIntrinsicSize();
if (rfSize.width.GetUnit() == eStyleUnit_Coord)
aSize->width = rfSize.width.GetCoordValue();
if (rfSize.height.GetUnit() == eStyleUnit_Coord)

View File

@@ -13,6 +13,7 @@
#include "mozilla/dom/Element.h"
#include "nsRegion.h"
#include "nsDeviceContext.h"
#include "nsIFrame.h"
#include <algorithm>
namespace mozilla {

View File

@@ -2638,7 +2638,7 @@ ElementRestyler::InitializeAccessibilityNotifications()
// it is not inside a {ib} split or is the first frame of {ib} split.
if (nsIPresShell::IsAccessibilityActive() &&
!mFrame->GetPrevContinuation() &&
!nsLayoutUtils::FrameIsNonFirstInIBSplit(mFrame)) {
!mFrame->FrameIsNonFirstInIBSplit()) {
if (mDesiredA11yNotifications == eSendAllNotifications) {
bool isFrameVisible = mFrame->StyleVisibility()->IsVisible();
if (isFrameVisible != mWasFrameVisible) {

View File

@@ -1310,7 +1310,7 @@ nsBidiPresUtils::IsLeftOrRightMost(nsIFrame* aFrame,
// endmost or anything except the first part as startmost.
// As an optimization, only get the first continuation once.
nsIFrame* firstContinuation = aFrame->FirstContinuation();
if (nsLayoutUtils::FrameIsNonLastInIBSplit(firstContinuation)) {
if (firstContinuation->FrameIsNonLastInIBSplit()) {
// We are not endmost
if (isLTR) {
aIsRightMost = false;
@@ -1318,7 +1318,7 @@ nsBidiPresUtils::IsLeftOrRightMost(nsIFrame* aFrame,
aIsLeftMost = false;
}
}
if (nsLayoutUtils::FrameIsNonFirstInIBSplit(firstContinuation)) {
if (firstContinuation->FrameIsNonFirstInIBSplit()) {
// We are not startmost
if (isLTR) {
aIsLeftMost = false;
@@ -1452,7 +1452,7 @@ nsBidiPresUtils::RepositionInlineFrames(BidiLineData *aBld,
// have been reflowed, which is required for GetUsedMargin/Border/Padding
nsMargin margin = aFirstChild->GetUsedMargin();
if (!aFirstChild->GetPrevContinuation() &&
!nsLayoutUtils::FrameIsNonFirstInIBSplit(aFirstChild))
!aFirstChild->FrameIsNonFirstInIBSplit())
leftSpace = isLTR ? margin.left : margin.right;
nscoord left = aFirstChild->GetPosition().x - leftSpace;

View File

@@ -11,6 +11,8 @@
#include "gfxBlur.h"
#include "gfxContext.h"
#include "nsLayoutUtils.h"
#include "nsStyleStruct.h"
#include "nsIFrame.h"
class nsStyleContext;
class nsPresContext;

View File

@@ -630,7 +630,7 @@ GetLastChildFrame(nsIFrame* aFrame,
}
//static
nsIFrame::ChildListID
FrameChildListID
nsLayoutUtils::GetChildListNameFor(nsIFrame* aChildFrame)
{
nsIFrame::ChildListID id = nsIFrame::kPrincipalList;
@@ -3133,7 +3133,7 @@ nsLayoutUtils::ComputeHeightDependentValue(
/* static */ nsSize
nsLayoutUtils::ComputeSizeWithIntrinsicDimensions(
nsRenderingContext* aRenderingContext, nsIFrame* aFrame,
const nsIFrame::IntrinsicSize& aIntrinsicSize,
const IntrinsicSize& aIntrinsicSize,
nsSize aIntrinsicRatio, nsSize aCBSize,
nsSize aMargin, nsSize aBorder, nsSize aPadding)
{
@@ -3458,7 +3458,7 @@ nsLayoutUtils::ComputeAutoSizeWithIntrinsicDimensions(nscoord minWidth, nscoord
nsLayoutUtils::MinWidthFromInline(nsIFrame* aFrame,
nsRenderingContext* aRenderingContext)
{
NS_ASSERTION(!nsLayoutUtils::IsContainerForFontSizeInflation(aFrame),
NS_ASSERTION(!aFrame->IsContainerForFontSizeInflation(),
"should not be container for font size inflation");
nsIFrame::InlineMinWidthData data;
@@ -3472,7 +3472,7 @@ nsLayoutUtils::MinWidthFromInline(nsIFrame* aFrame,
nsLayoutUtils::PrefWidthFromInline(nsIFrame* aFrame,
nsRenderingContext* aRenderingContext)
{
NS_ASSERTION(!nsLayoutUtils::IsContainerForFontSizeInflation(aFrame),
NS_ASSERTION(!aFrame->IsContainerForFontSizeInflation(),
"should not be container for font size inflation");
nsIFrame::InlinePrefWidthData data;
@@ -5221,25 +5221,6 @@ nsUnsetAttrRunnable::Run()
return mContent->UnsetAttr(kNameSpaceID_None, mAttrName, true);
}
nsReflowFrameRunnable::nsReflowFrameRunnable(nsIFrame* aFrame,
nsIPresShell::IntrinsicDirty aIntrinsicDirty,
nsFrameState aBitToAdd)
: mWeakFrame(aFrame),
mIntrinsicDirty(aIntrinsicDirty),
mBitToAdd(aBitToAdd)
{
}
NS_IMETHODIMP
nsReflowFrameRunnable::Run()
{
if (mWeakFrame.IsAlive()) {
mWeakFrame->PresContext()->PresShell()->
FrameNeedsReflow(mWeakFrame, mIntrinsicDirty, mBitToAdd);
}
return NS_OK;
}
/**
* Compute the minimum font size inside of a container with the given
* width, such that **when the user zooms the container to fill the full
@@ -5298,7 +5279,7 @@ nsLayoutUtils::FontSizeInflationInner(const nsIFrame *aFrame,
// non-inline element with fixed width or height, then we should not inflate
// fonts for this frame.
for (const nsIFrame* f = aFrame;
f && !IsContainerForFontSizeInflation(f);
f && !f->IsContainerForFontSizeInflation();
f = f->GetParent()) {
nsIContent* content = f->GetContent();
nsIAtom* fType = f->GetType();
@@ -5391,7 +5372,7 @@ nsLayoutUtils::InflationMinFontSizeFor(const nsIFrame *aFrame)
}
for (const nsIFrame *f = aFrame; f; f = f->GetParent()) {
if (IsContainerForFontSizeInflation(f)) {
if (f->IsContainerForFontSizeInflation()) {
if (!ShouldInflateFontsForContainer(f)) {
return 0;
}
@@ -5544,3 +5525,46 @@ nsLayoutUtils::UpdateImageVisibilityForFrame(nsIFrame* aImageFrame)
presShell->RemoveImageFromVisibleList(content);
}
}
nsLayoutUtils::SurfaceFromElementResult::SurfaceFromElementResult()
// Use safe default values here
: mIsWriteOnly(true), mIsStillLoading(false), mCORSUsed(false)
{
}
bool
nsLayoutUtils::IsNonWrapperBlock(nsIFrame* aFrame)
{
return GetAsBlock(aFrame) && !aFrame->IsBlockWrapper();
}
bool
nsLayoutUtils::NeedsPrintPreviewBackground(nsPresContext* aPresContext)
{
return aPresContext->IsRootPaginatedDocument() &&
(aPresContext->Type() == nsPresContext::eContext_PrintPreview ||
aPresContext->Type() == nsPresContext::eContext_PageLayout);
}
AutoMaybeDisableFontInflation::AutoMaybeDisableFontInflation(nsIFrame *aFrame)
{
// FIXME: Now that inflation calculations are based on the flow
// root's NCA's (nearest common ancestor of its inflatable
// descendants) width, we could probably disable inflation in
// fewer cases than we currently do.
if (aFrame->IsContainerForFontSizeInflation()) {
mPresContext = aFrame->PresContext();
mOldValue = mPresContext->mInflationDisabledForShrinkWrap;
mPresContext->mInflationDisabledForShrinkWrap = true;
} else {
// indicate we have nothing to restore
mPresContext = nullptr;
}
}
AutoMaybeDisableFontInflation::~AutoMaybeDisableFontInflation()
{
if (mPresContext) {
mPresContext->mInflationDisabledForShrinkWrap = mOldValue;
}
}

View File

@@ -24,25 +24,40 @@ class nsBlockFrame;
class gfxDrawable;
class nsView;
class imgIContainer;
class nsIFrame;
class nsStyleCoord;
class nsStyleCorners;
class gfxContext;
class nsPIDOMWindow;
class imgIRequest;
class nsIDocument;
struct nsStyleFont;
struct nsStyleImageOrientation;
struct nsOverflowAreas;
#include "mozilla/MemoryReporting.h"
#include "nsChangeHint.h"
#include "nsAutoPtr.h"
#include "nsIFrame.h"
#include "nsFrameList.h"
#include "nsThreadUtils.h"
#include "nsIPresShell.h"
#include "nsIPrincipal.h"
#include "gfxPattern.h"
#include "nsCSSPseudoElements.h"
#include "FrameMetrics.h"
#include "gfx3DMatrix.h"
#include "nsIWidget.h"
#include "nsCSSProperty.h"
#include "nsStyleCoord.h"
#include "nsStyleConsts.h"
#include "nsGkAtoms.h"
#include "nsRuleNode.h"
#include <limits>
#include <algorithm>
namespace mozilla {
class SVGImageContext;
struct IntrinsicSize;
namespace dom {
class Element;
class HTMLImageElement;
@@ -101,7 +116,7 @@ public:
* Use heuristics to figure out the child list that
* aChildFrame is currently in.
*/
static nsIFrame::ChildListID GetChildListNameFor(nsIFrame* aChildFrame);
static mozilla::layout::FrameChildListID GetChildListNameFor(nsIFrame* aChildFrame);
/**
* GetBeforeFrame returns the outermost :before frame of the given frame, if
@@ -258,23 +273,6 @@ public:
int32_t aIf2Ancestor,
nsIFrame* aCommonAncestor = nullptr);
/**
* Sorts the given nsFrameList, so that for every two adjacent frames in the
* list, the former is less than or equal to the latter, according to the
* templated IsLessThanOrEqual method.
*
* Note: this method uses a stable merge-sort algorithm.
*/
template<bool IsLessThanOrEqual(nsIFrame*, nsIFrame*)>
static void SortFrameList(nsFrameList& aFrameList);
/**
* Returns true if the given frame list is already sorted, according to the
* templated IsLessThanOrEqual function.
*/
template<bool IsLessThanOrEqual(nsIFrame*, nsIFrame*)>
static bool IsFrameListSorted(nsFrameList& aFrameList);
/**
* LastContinuationWithChild gets the last continuation in aFrame's chain
* that has a child, or the first continuation if the frame has no children.
@@ -915,9 +913,7 @@ public:
/*
* Whether the frame is an nsBlockFrame which is not a wrapper block.
*/
static bool IsNonWrapperBlock(nsIFrame* aFrame) {
return GetAsBlock(aFrame) && !aFrame->IsBlockWrapper();
}
static bool IsNonWrapperBlock(nsIFrame* aFrame);
/**
* If aFrame is an out of flow frame, return its placeholder, otherwise
@@ -1020,7 +1016,7 @@ public:
nscoord aContentEdgeToBoxSizingBoxEdge,
const nsStyleCoord& aCoord)
{
MOZ_ASSERT(aContainingBlockHeight != NS_AUTOHEIGHT || !aCoord.HasPercent(),
MOZ_ASSERT(aContainingBlockHeight != nscoord_MAX || !aCoord.HasPercent(),
"caller must deal with %% of unconstrained height");
MOZ_ASSERT(aCoord.IsCoordPercentCalcUnit());
@@ -1035,7 +1031,7 @@ public:
nsStyleUnit unit = aCoord.GetUnit();
return unit == eStyleUnit_Auto || // only for 'height'
unit == eStyleUnit_None || // only for 'max-height'
(aCBHeight == NS_AUTOHEIGHT && aCoord.HasPercent());
(aCBHeight == nscoord_MAX && aCoord.HasPercent());
}
static bool IsPaddingZero(const nsStyleCoord &aCoord)
@@ -1068,7 +1064,7 @@ public:
*/
static nsSize ComputeSizeWithIntrinsicDimensions(
nsRenderingContext* aRenderingContext, nsIFrame* aFrame,
const nsIFrame::IntrinsicSize& aIntrinsicSize,
const mozilla::IntrinsicSize& aIntrinsicSize,
nsSize aIntrinsicRatio, nsSize aCBSize,
nsSize aMargin, nsSize aBorder, nsSize aPadding);
@@ -1468,26 +1464,6 @@ public:
*/
static bool IsReallyFixedPos(nsIFrame* aFrame);
/**
* Return true if aFrame is in an {ib} split and is NOT one of the
* continuations of the first inline in it.
*/
static bool FrameIsNonFirstInIBSplit(const nsIFrame* aFrame) {
return (aFrame->GetStateBits() & NS_FRAME_IS_SPECIAL) &&
aFrame->FirstContinuation()->
Properties().Get(nsIFrame::IBSplitSpecialPrevSibling());
}
/**
* Return true if aFrame is in an {ib} split and is NOT one of the
* continuations of the last inline in it.
*/
static bool FrameIsNonLastInIBSplit(const nsIFrame* aFrame) {
return (aFrame->GetStateBits() & NS_FRAME_IS_SPECIAL) &&
aFrame->FirstContinuation()->
Properties().Get(nsIFrame::IBSplitSpecialSibling());
}
/**
* Obtain a gfxASurface from the given DOM element, if possible.
* This obtains the most natural surface from the element; that
@@ -1523,9 +1499,7 @@ public:
};
struct SurfaceFromElementResult {
SurfaceFromElementResult() :
// Use safe default values here
mIsWriteOnly(true), mIsStillLoading(false), mCORSUsed(false) {}
SurfaceFromElementResult();
/* mSurface will contain the resulting surface, or will be NULL on error */
nsRefPtr<gfxASurface> mSurface;
@@ -1586,11 +1560,7 @@ public:
* Returns true if the passed in prescontext needs the dark grey background
* that goes behind the page of a print preview presentation.
*/
static bool NeedsPrintPreviewBackground(nsPresContext* aPresContext) {
return aPresContext->IsRootPaginatedDocument() &&
(aPresContext->Type() == nsPresContext::eContext_PrintPreview ||
aPresContext->Type() == nsPresContext::eContext_PageLayout);
}
static bool NeedsPrintPreviewBackground(nsPresContext* aPresContext);
/**
* Adds all font faces used in the frame tree starting from aFrame
@@ -1679,15 +1649,6 @@ public:
static void UnionChildOverflow(nsIFrame* aFrame,
nsOverflowAreas& aOverflowAreas);
/**
* Return whether this is a frame whose width is used when computing
* the font size inflation of its descendants.
*/
static bool IsContainerForFontSizeInflation(const nsIFrame *aFrame)
{
return aFrame->GetStateBits() & NS_FRAME_FONT_INFLATION_CONTAINER;
}
/**
* Return the font size inflation *ratio* for a given frame. This is
* the factor by which font sizes should be inflated; it is never
@@ -1900,13 +1861,6 @@ public:
UpdateImageVisibilityForFrame(nsIFrame* aImageFrame);
private:
// Helper-functions for SortFrameList():
template<bool IsLessThanOrEqual(nsIFrame*, nsIFrame*)>
static nsIFrame* SortedMerge(nsIFrame *aLeft, nsIFrame *aRight);
template<bool IsLessThanOrEqual(nsIFrame*, nsIFrame*)>
static nsIFrame* MergeSort(nsIFrame *aSource);
static uint32_t sFontSizeInflationEmPerLine;
static uint32_t sFontSizeInflationMinTwips;
static uint32_t sFontSizeInflationLineThreshold;
@@ -1917,138 +1871,6 @@ private:
static bool sInvalidationDebuggingIsEnabled;
};
// Helper-functions for nsLayoutUtils::SortFrameList()
// ---------------------------------------------------
template<bool IsLessThanOrEqual(nsIFrame*, nsIFrame*)>
/* static */ nsIFrame*
nsLayoutUtils::SortedMerge(nsIFrame *aLeft, nsIFrame *aRight)
{
NS_PRECONDITION(aLeft && aRight, "SortedMerge must have non-empty lists");
nsIFrame *result;
// Unroll first iteration to avoid null-check 'result' inside the loop.
if (IsLessThanOrEqual(aLeft, aRight)) {
result = aLeft;
aLeft = aLeft->GetNextSibling();
if (!aLeft) {
result->SetNextSibling(aRight);
return result;
}
}
else {
result = aRight;
aRight = aRight->GetNextSibling();
if (!aRight) {
result->SetNextSibling(aLeft);
return result;
}
}
nsIFrame *last = result;
for (;;) {
if (IsLessThanOrEqual(aLeft, aRight)) {
last->SetNextSibling(aLeft);
last = aLeft;
aLeft = aLeft->GetNextSibling();
if (!aLeft) {
last->SetNextSibling(aRight);
return result;
}
}
else {
last->SetNextSibling(aRight);
last = aRight;
aRight = aRight->GetNextSibling();
if (!aRight) {
last->SetNextSibling(aLeft);
return result;
}
}
}
}
template<bool IsLessThanOrEqual(nsIFrame*, nsIFrame*)>
/* static */ nsIFrame*
nsLayoutUtils::MergeSort(nsIFrame *aSource)
{
NS_PRECONDITION(aSource, "MergeSort null arg");
nsIFrame *sorted[32] = { nullptr };
nsIFrame **fill = &sorted[0];
nsIFrame **left;
nsIFrame *rest = aSource;
do {
nsIFrame *current = rest;
rest = rest->GetNextSibling();
current->SetNextSibling(nullptr);
// Merge it with sorted[0] if present; then merge the result with sorted[1] etc.
// sorted[0] is a list of length 1 (or nullptr).
// sorted[1] is a list of length 2 (or nullptr).
// sorted[2] is a list of length 4 (or nullptr). etc.
for (left = &sorted[0]; left != fill && *left; ++left) {
current = SortedMerge<IsLessThanOrEqual>(*left, current);
*left = nullptr;
}
// Fill the empty slot that we couldn't merge with the last result.
*left = current;
if (left == fill)
++fill;
} while (rest);
// Collect and merge the results.
nsIFrame *result = nullptr;
for (left = &sorted[0]; left != fill; ++left) {
if (*left) {
result = result ? SortedMerge<IsLessThanOrEqual>(*left, result) : *left;
}
}
return result;
}
template<bool IsLessThanOrEqual(nsIFrame*, nsIFrame*)>
/* static */ void
nsLayoutUtils::SortFrameList(nsFrameList& aFrameList)
{
nsIFrame* head = MergeSort<IsLessThanOrEqual>(aFrameList.FirstChild());
aFrameList = nsFrameList(head, GetLastSibling(head));
MOZ_ASSERT(IsFrameListSorted<IsLessThanOrEqual>(aFrameList),
"After we sort a frame list, it should be in sorted order...");
}
template<bool IsLessThanOrEqual(nsIFrame*, nsIFrame*)>
/* static */ bool
nsLayoutUtils::IsFrameListSorted(nsFrameList& aFrameList)
{
if (aFrameList.IsEmpty()) {
// empty lists are trivially sorted.
return true;
}
// We'll walk through the list with two iterators, one trailing behind the
// other. The list is sorted IFF trailingIter <= iter, across the whole list.
nsFrameList::Enumerator trailingIter(aFrameList);
nsFrameList::Enumerator iter(aFrameList);
iter.Next(); // Skip |iter| past first frame. (List is nonempty, so we can.)
// Now, advance the iterators in parallel, comparing each adjacent pair.
while (!iter.AtEnd()) {
MOZ_ASSERT(!trailingIter.AtEnd(), "trailing iter shouldn't finish first");
if (!IsLessThanOrEqual(trailingIter.get(), iter.get())) {
return false;
}
trailingIter.Next();
iter.Next();
}
// We made it to the end without returning early, so the list is sorted.
return true;
}
template<typename PointType, typename RectType, typename CoordType>
/* static */ bool
nsLayoutUtils::PointIsCloserToRect(PointType aPoint, const RectType& aRect,
@@ -2101,28 +1923,9 @@ namespace mozilla {
*/
class AutoMaybeDisableFontInflation {
public:
AutoMaybeDisableFontInflation(nsIFrame *aFrame)
{
// FIXME: Now that inflation calculations are based on the flow
// root's NCA's (nearest common ancestor of its inflatable
// descendants) width, we could probably disable inflation in
// fewer cases than we currently do.
if (nsLayoutUtils::IsContainerForFontSizeInflation(aFrame)) {
mPresContext = aFrame->PresContext();
mOldValue = mPresContext->mInflationDisabledForShrinkWrap;
mPresContext->mInflationDisabledForShrinkWrap = true;
} else {
// indicate we have nothing to restore
mPresContext = nullptr;
}
}
AutoMaybeDisableFontInflation(nsIFrame *aFrame);
~AutoMaybeDisableFontInflation()
{
if (mPresContext) {
mPresContext->mInflationDisabledForShrinkWrap = mOldValue;
}
}
~AutoMaybeDisableFontInflation();
private:
nsPresContext *mPresContext;
bool mOldValue;
@@ -2157,18 +1960,4 @@ public:
nsCOMPtr<nsIAtom> mAttrName;
};
class nsReflowFrameRunnable : public nsRunnable
{
public:
nsReflowFrameRunnable(nsIFrame* aFrame,
nsIPresShell::IntrinsicDirty aIntrinsicDirty,
nsFrameState aBitToAdd);
NS_DECL_NSIRUNNABLE
nsWeakFrame mWeakFrame;
nsIPresShell::IntrinsicDirty mIntrinsicDirty;
nsFrameState mBitToAdd;
};
#endif // nsLayoutUtils_h__

View File

@@ -1116,11 +1116,11 @@ template<bool IsLessThanOrEqual(nsIFrame*, nsIFrame*)>
/* static */ bool
nsFlexContainerFrame::SortChildrenIfNeeded()
{
if (nsLayoutUtils::IsFrameListSorted<IsLessThanOrEqual>(mFrames)) {
if (nsIFrame::IsFrameListSorted<IsLessThanOrEqual>(mFrames)) {
return false;
}
nsLayoutUtils::SortFrameList<IsLessThanOrEqual>(mFrames);
nsIFrame::SortFrameList<IsLessThanOrEqual>(mFrames);
return true;
}
@@ -1163,7 +1163,7 @@ nsFlexContainerFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
const nsDisplayListSet& aLists)
{
NS_ASSERTION(
nsLayoutUtils::IsFrameListSorted<IsOrderLEQWithDOMFallback>(mFrames),
nsIFrame::IsFrameListSorted<IsOrderLEQWithDOMFallback>(mFrames),
"Child frames aren't sorted correctly");
DisplayBorderBackgroundOutline(aBuilder, aLists);

View File

@@ -202,7 +202,7 @@ nsFontInflationData::UpdateWidth(const nsHTMLReflowState &aReflowState)
nsIFrame *nca = NearestCommonAncestorFirstInFlow(firstInflatableDescendant,
lastInflatableDescendant,
bfc);
while (!nsLayoutUtils::IsContainerForFontSizeInflation(nca)) {
while (!nca->IsContainerForFontSizeInflation()) {
nca = nca->GetParent()->FirstInFlow();
}

View File

@@ -3878,7 +3878,7 @@ nsFrame::IntrinsicWidthOffsets(nsRenderingContext* aRenderingContext)
return result;
}
/* virtual */ nsIFrame::IntrinsicSize
/* virtual */ IntrinsicSize
nsFrame::GetIntrinsicSize()
{
return IntrinsicSize(); // default is width/height set to eStyleUnit_None

View File

@@ -257,7 +257,7 @@ public:
InlinePrefWidthData *aData) MOZ_OVERRIDE;
virtual IntrinsicWidthOffsetData
IntrinsicWidthOffsets(nsRenderingContext* aRenderingContext) MOZ_OVERRIDE;
virtual IntrinsicSize GetIntrinsicSize() MOZ_OVERRIDE;
virtual mozilla::IntrinsicSize GetIntrinsicSize() MOZ_OVERRIDE;
virtual nsSize GetIntrinsicRatio() MOZ_OVERRIDE;
virtual nsSize ComputeSize(nsRenderingContext *aRenderingContext,

View File

@@ -431,10 +431,7 @@ public:
mPrev = aOther.mPrev;
}
void Next() {
mPrev = mFrame;
Enumerator::Next();
}
inline void Next();
bool AtEnd() const { return Enumerator::AtEnd(); }

View File

@@ -33,6 +33,7 @@
#include <algorithm>
#include "nsITheme.h"
#include "gfx3DMatrix.h"
#include "nsLayoutUtils.h"
#ifdef ACCESSIBILITY
#include "mozilla/a11y/AccTypes.h"
@@ -543,6 +544,35 @@ MOZ_END_ENUM_CLASS(nsDidReflowStatus)
#define NS_FRAME_OVERFLOW_LARGE 0x000000ff // overflow is stored as a
// separate rect property
namespace mozilla {
/*
* For replaced elements only. Gets the intrinsic dimensions of this element.
* The dimensions may only be one of the following two types:
*
* eStyleUnit_Coord - a length in app units
* eStyleUnit_None - the element has no intrinsic size in this dimension
*/
struct IntrinsicSize {
nsStyleCoord width, height;
IntrinsicSize()
: width(eStyleUnit_None), height(eStyleUnit_None)
{}
IntrinsicSize(const IntrinsicSize& rhs)
: width(rhs.width), height(rhs.height)
{}
IntrinsicSize& operator=(const IntrinsicSize& rhs) {
width = rhs.width; height = rhs.height; return *this;
}
bool operator==(const IntrinsicSize& rhs) {
return width == rhs.width && height == rhs.height;
}
bool operator!=(const IntrinsicSize& rhs) {
return !(*this == rhs);
}
};
}
//----------------------------------------------------------------------
/**
@@ -1709,33 +1739,7 @@ public:
virtual IntrinsicWidthOffsetData
IntrinsicWidthOffsets(nsRenderingContext* aRenderingContext) = 0;
/*
* For replaced elements only. Gets the intrinsic dimensions of this element.
* The dimensions may only be one of the following two types:
*
* eStyleUnit_Coord - a length in app units
* eStyleUnit_None - the element has no intrinsic size in this dimension
*/
struct IntrinsicSize {
nsStyleCoord width, height;
IntrinsicSize()
: width(eStyleUnit_None), height(eStyleUnit_None)
{}
IntrinsicSize(const IntrinsicSize& rhs)
: width(rhs.width), height(rhs.height)
{}
IntrinsicSize& operator=(const IntrinsicSize& rhs) {
width = rhs.width; height = rhs.height; return *this;
}
bool operator==(const IntrinsicSize& rhs) {
return width == rhs.width && height == rhs.height;
}
bool operator!=(const IntrinsicSize& rhs) {
return !(*this == rhs);
}
};
virtual IntrinsicSize GetIntrinsicSize() = 0;
virtual mozilla::IntrinsicSize GetIntrinsicSize() = 0;
/*
* Get the intrinsic ratio of this element, or nsSize(0,0) if it has
@@ -2963,6 +2967,49 @@ NS_PTR_TO_INT32(frame->Properties().Get(nsIFrame::ParagraphDepthProperty()))
*/
static void RemoveInPopupStateBitFromDescendants(nsIFrame* aFrame);
/**
* Sorts the given nsFrameList, so that for every two adjacent frames in the
* list, the former is less than or equal to the latter, according to the
* templated IsLessThanOrEqual method.
*
* Note: this method uses a stable merge-sort algorithm.
*/
template<bool IsLessThanOrEqual(nsIFrame*, nsIFrame*)>
static void SortFrameList(nsFrameList& aFrameList);
/**
* Returns true if the given frame list is already sorted, according to the
* templated IsLessThanOrEqual function.
*/
template<bool IsLessThanOrEqual(nsIFrame*, nsIFrame*)>
static bool IsFrameListSorted(nsFrameList& aFrameList);
/**
* Return true if aFrame is in an {ib} split and is NOT one of the
* continuations of the first inline in it.
*/
bool FrameIsNonFirstInIBSplit() const {
return (GetStateBits() & NS_FRAME_IS_SPECIAL) &&
FirstContinuation()->Properties().Get(nsIFrame::IBSplitSpecialPrevSibling());
}
/**
* Return true if aFrame is in an {ib} split and is NOT one of the
* continuations of the last inline in it.
*/
bool FrameIsNonLastInIBSplit() const {
return (GetStateBits() & NS_FRAME_IS_SPECIAL) &&
FirstContinuation()->Properties().Get(nsIFrame::IBSplitSpecialSibling());
}
/**
* Return whether this is a frame whose width is used when computing
* the font size inflation of its descendants.
*/
bool IsContainerForFontSizeInflation() const {
return GetStateBits() & NS_FRAME_FONT_INFLATION_CONTAINER;
}
protected:
// Members
nsRect mRect;
@@ -3143,6 +3190,13 @@ private:
bool SetOverflowAreas(const nsOverflowAreas& aOverflowAreas);
nsPoint GetOffsetToCrossDoc(const nsIFrame* aOther, const int32_t aAPD) const;
// Helper-functions for SortFrameList():
template<bool IsLessThanOrEqual(nsIFrame*, nsIFrame*)>
static nsIFrame* SortedMerge(nsIFrame *aLeft, nsIFrame *aRight);
template<bool IsLessThanOrEqual(nsIFrame*, nsIFrame*)>
static nsIFrame* MergeSort(nsIFrame *aSource);
#ifdef DEBUG
public:
static void IndentBy(FILE* out, int32_t aIndent) {
@@ -3307,6 +3361,145 @@ FrameLinkEnumerator(const nsFrameList& aList, nsIFrame* aPrevFrame)
mFrame = aPrevFrame ? aPrevFrame->GetNextSibling() : aList.FirstChild();
}
inline void
nsFrameList::FrameLinkEnumerator::Next()
{
mPrev = mFrame;
Enumerator::Next();
}
// Helper-functions for nsIFrame::SortFrameList()
// ---------------------------------------------------
template<bool IsLessThanOrEqual(nsIFrame*, nsIFrame*)>
/* static */ nsIFrame*
nsIFrame::SortedMerge(nsIFrame *aLeft, nsIFrame *aRight)
{
NS_PRECONDITION(aLeft && aRight, "SortedMerge must have non-empty lists");
nsIFrame *result;
// Unroll first iteration to avoid null-check 'result' inside the loop.
if (IsLessThanOrEqual(aLeft, aRight)) {
result = aLeft;
aLeft = aLeft->GetNextSibling();
if (!aLeft) {
result->SetNextSibling(aRight);
return result;
}
}
else {
result = aRight;
aRight = aRight->GetNextSibling();
if (!aRight) {
result->SetNextSibling(aLeft);
return result;
}
}
nsIFrame *last = result;
for (;;) {
if (IsLessThanOrEqual(aLeft, aRight)) {
last->SetNextSibling(aLeft);
last = aLeft;
aLeft = aLeft->GetNextSibling();
if (!aLeft) {
last->SetNextSibling(aRight);
return result;
}
}
else {
last->SetNextSibling(aRight);
last = aRight;
aRight = aRight->GetNextSibling();
if (!aRight) {
last->SetNextSibling(aLeft);
return result;
}
}
}
}
template<bool IsLessThanOrEqual(nsIFrame*, nsIFrame*)>
/* static */ nsIFrame*
nsIFrame::MergeSort(nsIFrame *aSource)
{
NS_PRECONDITION(aSource, "MergeSort null arg");
nsIFrame *sorted[32] = { nullptr };
nsIFrame **fill = &sorted[0];
nsIFrame **left;
nsIFrame *rest = aSource;
do {
nsIFrame *current = rest;
rest = rest->GetNextSibling();
current->SetNextSibling(nullptr);
// Merge it with sorted[0] if present; then merge the result with sorted[1] etc.
// sorted[0] is a list of length 1 (or nullptr).
// sorted[1] is a list of length 2 (or nullptr).
// sorted[2] is a list of length 4 (or nullptr). etc.
for (left = &sorted[0]; left != fill && *left; ++left) {
current = SortedMerge<IsLessThanOrEqual>(*left, current);
*left = nullptr;
}
// Fill the empty slot that we couldn't merge with the last result.
*left = current;
if (left == fill)
++fill;
} while (rest);
// Collect and merge the results.
nsIFrame *result = nullptr;
for (left = &sorted[0]; left != fill; ++left) {
if (*left) {
result = result ? SortedMerge<IsLessThanOrEqual>(*left, result) : *left;
}
}
return result;
}
template<bool IsLessThanOrEqual(nsIFrame*, nsIFrame*)>
/* static */ void
nsIFrame::SortFrameList(nsFrameList& aFrameList)
{
nsIFrame* head = MergeSort<IsLessThanOrEqual>(aFrameList.FirstChild());
aFrameList = nsFrameList(head, nsLayoutUtils::GetLastSibling(head));
MOZ_ASSERT(IsFrameListSorted<IsLessThanOrEqual>(aFrameList),
"After we sort a frame list, it should be in sorted order...");
}
template<bool IsLessThanOrEqual(nsIFrame*, nsIFrame*)>
/* static */ bool
nsIFrame::IsFrameListSorted(nsFrameList& aFrameList)
{
if (aFrameList.IsEmpty()) {
// empty lists are trivially sorted.
return true;
}
// We'll walk through the list with two iterators, one trailing behind the
// other. The list is sorted IFF trailingIter <= iter, across the whole list.
nsFrameList::Enumerator trailingIter(aFrameList);
nsFrameList::Enumerator iter(aFrameList);
iter.Next(); // Skip |iter| past first frame. (List is nonempty, so we can.)
// Now, advance the iterators in parallel, comparing each adjacent pair.
while (!iter.AtEnd()) {
MOZ_ASSERT(!trailingIter.AtEnd(), "trailing iter shouldn't finish first");
if (!IsLessThanOrEqual(trailingIter.get(), iter.get())) {
return false;
}
trailingIter.Next();
iter.Next();
}
// We made it to the end without returning early, so the list is sorted.
return true;
}
#include "nsStyleStructInlines.h"
bool

View File

@@ -265,8 +265,8 @@ nsImageFrame::UpdateIntrinsicSize(imgIContainer* aImage)
if (!aImage)
return false;
nsIFrame::IntrinsicSize oldIntrinsicSize = mIntrinsicSize;
mIntrinsicSize = nsIFrame::IntrinsicSize();
IntrinsicSize oldIntrinsicSize = mIntrinsicSize;
mIntrinsicSize = IntrinsicSize();
// Set intrinsic size to match aImage's reported intrinsic width & height.
nsSize intrinsicSize;
@@ -793,7 +793,7 @@ nsImageFrame::GetPrefWidth(nsRenderingContext *aRenderingContext)
mIntrinsicSize.width.GetCoordValue() : 0;
}
/* virtual */ nsIFrame::IntrinsicSize
/* virtual */ IntrinsicSize
nsImageFrame::GetIntrinsicSize()
{
return mIntrinsicSize;

View File

@@ -81,7 +81,7 @@ public:
const nsDisplayListSet& aLists) MOZ_OVERRIDE;
virtual nscoord GetMinWidth(nsRenderingContext *aRenderingContext);
virtual nscoord GetPrefWidth(nsRenderingContext *aRenderingContext);
virtual IntrinsicSize GetIntrinsicSize();
virtual mozilla::IntrinsicSize GetIntrinsicSize();
virtual nsSize GetIntrinsicRatio();
NS_IMETHOD Reflow(nsPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
@@ -286,7 +286,7 @@ private:
nsCOMPtr<imgIContainer> mImage;
nsSize mComputedSize;
nsIFrame::IntrinsicSize mIntrinsicSize;
mozilla::IntrinsicSize mIntrinsicSize;
nsSize mIntrinsicRatio;
bool mDisplayingIcon;

View File

@@ -132,8 +132,8 @@ nsInlineFrame::IsSelfEmpty()
// avoid having to get it twice..
nsIFrame* firstCont = FirstContinuation();
return
(!haveStart || nsLayoutUtils::FrameIsNonFirstInIBSplit(firstCont)) &&
(!haveEnd || nsLayoutUtils::FrameIsNonLastInIBSplit(firstCont));
(!haveStart || firstCont->FrameIsNonFirstInIBSplit()) &&
(!haveEnd || firstCont->FrameIsNonLastInIBSplit());
}
return false;
}
@@ -463,8 +463,7 @@ nsInlineFrame::ReflowFrames(nsPresContext* aPresContext,
nscoord leftEdge = 0;
// Don't offset by our start borderpadding if we have a prev continuation or
// if we're in a part of an {ib} split other than the first one.
if (!GetPrevContinuation() &&
!nsLayoutUtils::FrameIsNonFirstInIBSplit(this)) {
if (!GetPrevContinuation() && !FrameIsNonFirstInIBSplit()) {
leftEdge = ltr ? aReflowState.mComputedBorderPadding.left
: aReflowState.mComputedBorderPadding.right;
}
@@ -626,8 +625,7 @@ nsInlineFrame::ReflowFrames(nsPresContext* aPresContext,
// Make sure to not include our start border and padding if we have a prev
// continuation or if we're in a part of an {ib} split other than the first
// one.
if (!GetPrevContinuation() &&
!nsLayoutUtils::FrameIsNonFirstInIBSplit(this)) {
if (!GetPrevContinuation() && !FrameIsNonFirstInIBSplit()) {
aMetrics.width += ltr ? aReflowState.mComputedBorderPadding.left
: aReflowState.mComputedBorderPadding.right;
}
@@ -641,7 +639,7 @@ nsInlineFrame::ReflowFrames(nsPresContext* aPresContext,
*/
if (NS_FRAME_IS_COMPLETE(aStatus) &&
!LastInFlow()->GetNextContinuation() &&
!nsLayoutUtils::FrameIsNonLastInIBSplit(this)) {
!FrameIsNonLastInIBSplit()) {
aMetrics.width += ltr ? aReflowState.mComputedBorderPadding.right
: aReflowState.mComputedBorderPadding.left;
}
@@ -887,10 +885,10 @@ nsInlineFrame::GetSkipSides(const nsHTMLReflowState* aReflowState) const
// We're missing one of the skip bits, so check whether we need to set it.
// Only get the first continuation once, as an optimization.
nsIFrame* firstContinuation = FirstContinuation();
if (nsLayoutUtils::FrameIsNonLastInIBSplit(firstContinuation)) {
if (firstContinuation->FrameIsNonLastInIBSplit()) {
skip |= endBit;
}
if (nsLayoutUtils::FrameIsNonFirstInIBSplit(firstContinuation)) {
if (firstContinuation->FrameIsNonFirstInIBSplit()) {
skip |= startBit;
}
}

View File

@@ -685,7 +685,7 @@ IsPercentageAware(const nsIFrame* aFrame)
if (f->GetIntrinsicRatio() != nsSize(0, 0) &&
// Some percents are treated like 'auto', so check != coord
pos->mHeight.GetUnit() != eStyleUnit_Coord) {
const nsIFrame::IntrinsicSize &intrinsicSize = f->GetIntrinsicSize();
const IntrinsicSize &intrinsicSize = f->GetIntrinsicSize();
if (intrinsicSize.width.GetUnit() == eStyleUnit_None &&
intrinsicSize.height.GetUnit() == eStyleUnit_None) {
return true;
@@ -1066,7 +1066,7 @@ nsLineLayout::ApplyStartMargin(PerFrameData* pfd,
// only live on the first continuation, but we don't want to apply
// the start margin for later continuations anyway.
if (pfd->mFrame->GetPrevContinuation() ||
nsLayoutUtils::FrameIsNonFirstInIBSplit(pfd->mFrame)) {
pfd->mFrame->FrameIsNonFirstInIBSplit()) {
// Zero this out so that when we compute the max-element-width of
// the frame we will properly avoid adding in the starting margin.
if (ltr)
@@ -1146,7 +1146,7 @@ nsLineLayout::CanPlaceFrame(PerFrameData* pfd,
*/
if ((NS_FRAME_IS_NOT_COMPLETE(aStatus) ||
pfd->mFrame->LastInFlow()->GetNextContinuation() ||
nsLayoutUtils::FrameIsNonLastInIBSplit(pfd->mFrame))
pfd->mFrame->FrameIsNonLastInIBSplit())
&& !pfd->GetFlag(PFD_ISLETTERFRAME)) {
if (ltr)
pfd->mMargin.right = 0;

View File

@@ -546,7 +546,7 @@ nsSubDocumentFrame::GetPrefWidth(nsRenderingContext *aRenderingContext)
return result;
}
/* virtual */ nsIFrame::IntrinsicSize
/* virtual */ IntrinsicSize
nsSubDocumentFrame::GetIntrinsicSize()
{
nsIFrame* subDocRoot = ObtainIntrinsicSizeFrame();

View File

@@ -48,7 +48,7 @@ public:
virtual nscoord GetMinWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE;
virtual nscoord GetPrefWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE;
virtual IntrinsicSize GetIntrinsicSize() MOZ_OVERRIDE;
virtual mozilla::IntrinsicSize GetIntrinsicSize() MOZ_OVERRIDE;
virtual nsSize GetIntrinsicRatio() MOZ_OVERRIDE;
virtual nsSize ComputeAutoSize(nsRenderingContext *aRenderingContext,

View File

@@ -11,8 +11,12 @@
#include "nsMathMLOperators.h"
#include "nsIMathMLFrame.h"
#include "nsLayoutUtils.h"
#include "nsBoundingMetrics.h"
#include "nsIFrame.h"
class nsMathMLChar;
class nsCSSValue;
class nsDisplayListSet;
// Concrete base class with default methods that derived MathML frames can override
class nsMathMLFrame : public nsIMathMLFrame {

View File

@@ -14,6 +14,7 @@
#include "nsStyleAnimation.h"
#include "nsEventDispatcher.h"
#include "nsLayoutUtils.h"
#include "nsIFrame.h"
#include <math.h>
using namespace mozilla;

View File

@@ -231,7 +231,7 @@ nsSVGOuterSVGFrame::GetPrefWidth(nsRenderingContext *aRenderingContext)
return result;
}
/* virtual */ nsIFrame::IntrinsicSize
/* virtual */ IntrinsicSize
nsSVGOuterSVGFrame::GetIntrinsicSize()
{
// XXXjwatt Note that here we want to return the CSS width/height if they're

View File

@@ -42,7 +42,7 @@ public:
virtual nscoord GetMinWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE;
virtual nscoord GetPrefWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE;
virtual IntrinsicSize GetIntrinsicSize() MOZ_OVERRIDE;
virtual mozilla::IntrinsicSize GetIntrinsicSize() MOZ_OVERRIDE;
virtual nsSize GetIntrinsicRatio() MOZ_OVERRIDE;
virtual nsSize ComputeSize(nsRenderingContext *aRenderingContext,

View File

@@ -40,6 +40,7 @@
#include "SVGNumberList.h"
#include "SVGPathElement.h"
#include "SVGTextPathElement.h"
#include "nsLayoutUtils.h"
#include <algorithm>
#include <cmath>
#include <limits>

View File

@@ -62,6 +62,7 @@
#include "nsDisplayList.h"
#include "mozilla/Preferences.h"
#include "nsThemeConstants.h"
#include "nsLayoutUtils.h"
#include <algorithm>
// Needed for Print Preview
@@ -1910,8 +1911,8 @@ void
nsBoxFrame::CheckBoxOrder()
{
if (SupportsOrdinalsInChildren() &&
!nsLayoutUtils::IsFrameListSorted<IsBoxOrdinalLEQ>(mFrames)) {
nsLayoutUtils::SortFrameList<IsBoxOrdinalLEQ>(mFrames);
!nsIFrame::IsFrameListSorted<IsBoxOrdinalLEQ>(mFrames)) {
nsIFrame::SortFrameList<IsBoxOrdinalLEQ>(mFrames);
}
}

View File

@@ -21,6 +21,40 @@
#include "nsIReflowCallback.h"
#include "nsContentUtils.h"
#include "mozilla/Attributes.h"
class nsReflowFrameRunnable : public nsRunnable
{
public:
nsReflowFrameRunnable(nsIFrame* aFrame,
nsIPresShell::IntrinsicDirty aIntrinsicDirty,
nsFrameState aBitToAdd);
NS_DECL_NSIRUNNABLE
nsWeakFrame mWeakFrame;
nsIPresShell::IntrinsicDirty mIntrinsicDirty;
nsFrameState mBitToAdd;
};
nsReflowFrameRunnable::nsReflowFrameRunnable(nsIFrame* aFrame,
nsIPresShell::IntrinsicDirty aIntrinsicDirty,
nsFrameState aBitToAdd)
: mWeakFrame(aFrame),
mIntrinsicDirty(aIntrinsicDirty),
mBitToAdd(aBitToAdd)
{
}
NS_IMETHODIMP
nsReflowFrameRunnable::Run()
{
if (mWeakFrame.IsAlive()) {
mWeakFrame->PresContext()->PresShell()->
FrameNeedsReflow(mWeakFrame, mIntrinsicDirty, mBitToAdd);
}
return NS_OK;
}
//
// NS_NewToolbarFrame
//