author | Ehsan Akhgari <ehsan@mozilla.com> |
Mon, 30 Sep 2013 17:26:04 -0400 | |
changeset 149384 | e8453cdce0057180b18cd1ba8514e279f24b0cf5 |
parent 149383 | cb856e6d57c1eeb387e3b57a5e4f95afc16f80cb |
child 149385 | b17120deb5b40081ab60402044439752b0ec5c64 |
push id | 25386 |
push user | emorley@mozilla.com |
push date | Tue, 01 Oct 2013 09:29:22 +0000 |
treeherder | mozilla-central@6856c45f3688 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | roc |
bugs | 921876 |
milestone | 27.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/content/canvas/src/DocumentRendererChild.cpp +++ b/content/canvas/src/DocumentRendererChild.cpp @@ -15,16 +15,18 @@ #include "nsComponentManagerUtils.h" #include "nsCSSParser.h" #include "nsPresContext.h" #include "nsCOMPtr.h" #include "nsColor.h" #include "gfxContext.h" #include "nsLayoutUtils.h" #include "nsContentUtils.h" +#include "nsCSSValue.h" +#include "nsRuleNode.h" using namespace mozilla::ipc; DocumentRendererChild::DocumentRendererChild() {} DocumentRendererChild::~DocumentRendererChild() {}
--- a/content/canvas/src/WebGLContext.h +++ b/content/canvas/src/WebGLContext.h @@ -17,16 +17,17 @@ #include "nsIDOMWebGLRenderingContext.h" #include "nsICanvasRenderingContextInternal.h" #include "mozilla/dom/HTMLCanvasElement.h" #include "nsWrapperCache.h" #include "nsIObserver.h" #include "GLContextProvider.h" +#include "gfxImageSurface.h" #include "mozilla/LinkedList.h" #include "mozilla/CheckedInt.h" #ifdef XP_MACOSX #include "ForceDiscreteGPUHelperCGL.h" #endif
--- a/content/events/src/Touch.cpp +++ b/content/events/src/Touch.cpp @@ -4,16 +4,17 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "mozilla/dom/Touch.h" #include "mozilla/dom/EventTarget.h" #include "mozilla/dom/TouchBinding.h" #include "nsContentUtils.h" #include "nsDOMTouchEvent.h" +#include "nsIContent.h" namespace mozilla { namespace dom { Touch::Touch(mozilla::dom::EventTarget* aTarget, int32_t aIdentifier, int32_t aPageX, int32_t aPageY,
--- a/content/events/src/nsDOMUIEvent.h +++ b/content/events/src/nsDOMUIEvent.h @@ -9,16 +9,18 @@ #include "mozilla/Attributes.h" #include "nsIDOMUIEvent.h" #include "nsDOMEvent.h" #include "nsLayoutUtils.h" #include "mozilla/dom/UIEventBinding.h" #include "nsPresContext.h" #include "nsDeviceContext.h" +class nsINode; + class nsDOMUIEvent : public nsDOMEvent, public nsIDOMUIEvent { typedef mozilla::CSSIntPoint CSSIntPoint; public: nsDOMUIEvent(mozilla::dom::EventTarget* aOwner, nsPresContext* aPresContext, nsGUIEvent* aEvent);
--- a/content/events/src/nsEventDispatcher.cpp +++ b/content/events/src/nsEventDispatcher.cpp @@ -6,16 +6,18 @@ #include "nsEventDispatcher.h" #include "nsPresContext.h" #include "nsEventListenerManager.h" #include "nsContentUtils.h" #include "nsCxPusher.h" #include "nsError.h" #include <new> +#include "nsIContent.h" +#include "nsIDocument.h" #include "nsINode.h" #include "nsPIDOMWindow.h" #include "nsDOMTouchEvent.h" #include "GeckoProfiler.h" #include "GeneratedEvents.h" #include "mozilla/ContentEvents.h" #include "mozilla/dom/EventTarget.h" #include "mozilla/MiscEvents.h"
--- a/dom/base/nsFocusManager.cpp +++ b/dom/base/nsFocusManager.cpp @@ -32,16 +32,17 @@ #include "nsFrameSelection.h" #include "mozilla/Selection.h" #include "nsXULPopupManager.h" #include "nsIScriptObjectPrincipal.h" #include "nsIPrincipal.h" #include "nsIObserverService.h" #include "nsIObjectFrame.h" #include "nsBindingManager.h" +#include "nsStyleCoord.h" #include "mozilla/ContentEvents.h" #include "mozilla/dom/Element.h" #include "mozilla/LookAndFeel.h" #include "mozilla/Preferences.h" #include "mozilla/Services.h" #include <algorithm>
--- a/dom/base/nsScreen.cpp +++ b/dom/base/nsScreen.cpp @@ -1,16 +1,17 @@ /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "mozilla/Hal.h" #include "nsScreen.h" #include "nsIDocShell.h" +#include "nsIDocument.h" #include "nsPresContext.h" #include "nsCOMPtr.h" #include "nsIDocShellTreeItem.h" #include "nsLayoutUtils.h" #include "nsDOMEvent.h" #include "nsJSUtils.h" #include "mozilla/dom/ScreenBinding.h" #include "nsDeviceContext.h"
--- a/image/src/VectorImage.cpp +++ b/image/src/VectorImage.cpp @@ -521,17 +521,17 @@ VectorImage::GetIntrinsicSize(nsSize* aS if (mError || !mIsFullyLoaded) return NS_ERROR_FAILURE; nsIFrame* rootFrame = mSVGDocumentWrapper->GetRootLayoutFrame(); if (!rootFrame) 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) aSize->height = rfSize.height.GetCoordValue(); return NS_OK; }
--- a/layout/base/PositionedEventTargeting.cpp +++ b/layout/base/PositionedEventTargeting.cpp @@ -8,16 +8,17 @@ #include "mozilla/Preferences.h" #include "nsLayoutUtils.h" #include "nsGkAtoms.h" #include "nsEventListenerManager.h" #include "nsPrintfCString.h" #include "mozilla/dom/Element.h" #include "nsRegion.h" #include "nsDeviceContext.h" +#include "nsIFrame.h" #include <algorithm> namespace mozilla { /* * The basic goal of FindFrameTargetedByInputEvent() is to find a good * target element that can respond to mouse events. Both mouse events and touch * events are targeted at this element. Note that even for touch events, we
--- a/layout/base/RestyleManager.cpp +++ b/layout/base/RestyleManager.cpp @@ -2633,17 +2633,17 @@ void ElementRestyler::InitializeAccessibilityNotifications() { #ifdef ACCESSIBILITY // Notify a11y for primary frame only if it's a root frame of visibility // changes or its parent frame was hidden while it stays visible and // 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) { if (isFrameVisible) { // Notify a11y the element (perhaps with its children) was shown. // We don't fall into this case if this element gets or stays shown // while its parent becomes hidden. mKidsDesiredA11yNotifications = eSkipNotifications;
--- a/layout/base/nsBidiPresUtils.cpp +++ b/layout/base/nsBidiPresUtils.cpp @@ -1305,25 +1305,25 @@ nsBidiPresUtils::IsLeftOrRightMost(nsIFr : !firstFrameState->mHasContOnPrevLines); if ((aIsLeftMost || aIsRightMost) && (aFrame->GetStateBits() & NS_FRAME_IS_SPECIAL)) { // For ib splits, don't treat anything except the last part as // 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; } else { aIsLeftMost = false; } } - if (nsLayoutUtils::FrameIsNonFirstInIBSplit(firstContinuation)) { + if (firstContinuation->FrameIsNonFirstInIBSplit()) { // We are not startmost if (isLTR) { aIsLeftMost = false; } else { aIsRightMost = false; } } } @@ -1447,17 +1447,17 @@ nsBidiPresUtils::RepositionInlineFrames( bool isLTR = (NS_STYLE_DIRECTION_LTR == vis->mDirection); nscoord leftSpace = 0; // This method is called from nsBlockFrame::PlaceLine via the call to // bidiUtils->ReorderFrames, so this is guaranteed to be after the inlines // 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; nsIFrame* frame; int32_t count = aBld->mVisualFrames.Length(); int32_t index; nsContinuationStates continuationStates;
--- a/layout/base/nsCSSRendering.h +++ b/layout/base/nsCSSRendering.h @@ -6,16 +6,18 @@ /* utility functions for drawing borders and backgrounds */ #ifndef nsCSSRendering_h___ #define nsCSSRendering_h___ #include "gfxBlur.h" #include "gfxContext.h" #include "nsLayoutUtils.h" +#include "nsStyleStruct.h" +#include "nsIFrame.h" class nsStyleContext; class nsPresContext; class nsRenderingContext; namespace mozilla { // A CSSSizeOrRatio represents a (possibly partially specified) size for use
--- a/layout/base/nsLayoutUtils.cpp +++ b/layout/base/nsLayoutUtils.cpp @@ -625,17 +625,17 @@ GetLastChildFrame(nsIFrame* aFrame return lastChildFrame; } return nullptr; } //static -nsIFrame::ChildListID +FrameChildListID nsLayoutUtils::GetChildListNameFor(nsIFrame* aChildFrame) { nsIFrame::ChildListID id = nsIFrame::kPrincipalList; if (aChildFrame->GetStateBits() & NS_FRAME_IS_OVERFLOW_CONTAINER) { nsIFrame* pif = aChildFrame->GetPrevInFlow(); if (pif->GetParent() == aChildFrame->GetParent()) { id = nsIFrame::kExcessOverflowContainersList; @@ -3128,17 +3128,17 @@ nsLayoutUtils::ComputeHeightDependentVal return 0; } #define MULDIV(a,b,c) (nscoord(int64_t(a) * int64_t(b) / int64_t(c))) /* 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) { const nsStylePosition* stylePos = aFrame->StylePosition(); // If we're a flex item, we'll compute our size a bit differently. const nsStyleCoord* widthStyleCoord = &(stylePos->mWidth); const nsStyleCoord* heightStyleCoord = &(stylePos->mHeight); @@ -3453,31 +3453,31 @@ nsLayoutUtils::ComputeAutoSizeWithIntrin return nsSize(width, height); } /* static */ 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; DISPLAY_MIN_WIDTH(aFrame, data.prevLines); aFrame->AddInlineMinWidth(aRenderingContext, &data); data.ForceBreak(aRenderingContext); return data.prevLines; } /* static */ nscoord 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; DISPLAY_PREF_WIDTH(aFrame, data.prevLines); aFrame->AddInlinePrefWidth(aRenderingContext, &data); data.ForceBreak(aRenderingContext); return data.prevLines; } @@ -5216,35 +5216,16 @@ nsUnsetAttrRunnable::nsUnsetAttrRunnable } NS_IMETHODIMP 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 * width of the device**, the fonts satisfy our minima. */ static nscoord MinimumFontSizeFor(nsPresContext* aPresContext, nscoord aContainerWidth) { @@ -5293,17 +5274,17 @@ nsLayoutUtils::FontSizeInflationInner(co // No need to scale. return 1.0; } // If between this current frame and its font inflation container there is a // 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(); // Also, if there is more than one frame corresponding to a single // content node, we want the outermost one. if (!(f->GetParent() && f->GetParent()->GetContent() == content) && // ignore width/height on inlines since they don't apply fType != nsGkAtoms::inlineFrame && @@ -5386,17 +5367,17 @@ nsLayoutUtils::InflationMinFontSizeFor(c { nsPresContext *presContext = aFrame->PresContext(); if (!FontSizeInflationEnabled(presContext) || presContext->mInflationDisabledForShrinkWrap) { return 0; } for (const nsIFrame *f = aFrame; f; f = f->GetParent()) { - if (IsContainerForFontSizeInflation(f)) { + if (f->IsContainerForFontSizeInflation()) { if (!ShouldInflateFontsForContainer(f)) { return 0; } nsFontInflationData *data = nsFontInflationData::FindFontInflationDataFor(aFrame); // FIXME: The need to null-check here is sort of a bug, and might // lead to incorrect results. @@ -5539,8 +5520,51 @@ nsLayoutUtils::UpdateImageVisibilityForF } if (visible) { presShell->EnsureImageInVisibleList(content); } else { 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; + } +}
--- a/layout/base/nsLayoutUtils.h +++ b/layout/base/nsLayoutUtils.h @@ -19,35 +19,50 @@ class nsFontMetrics; class nsClientRectList; class nsFontFaceList; class nsIImageLoadingContent; class nsStyleContext; 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; class HTMLCanvasElement; class HTMLVideoElement; } // namespace dom } // namespace mozilla @@ -96,17 +111,17 @@ public: * Get the critical display port for the given element. */ static bool GetCriticalDisplayPort(nsIContent* aContent, nsRect* aResult); /** * 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 * one exists. This is typically O(1). The frame passed in must be * the first-in-flow. * * @param aFrame the frame whose :before is wanted * @return the :before frame or nullptr if there isn't one @@ -254,33 +269,16 @@ public: */ static int32_t DoCompareTreePosition(nsIFrame* aFrame1, nsIFrame* aFrame2, int32_t aIf1Ancestor, 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. */ static nsIFrame* LastContinuationWithChild(nsIFrame* aFrame); /** * GetLastSibling simply finds the last sibling of aFrame, or returns nullptr if * aFrame is null. @@ -910,19 +908,17 @@ public: * Cast aFrame to an nsBlockFrame* or return null if it's not * an nsBlockFrame. */ static nsBlockFrame* GetAsBlock(nsIFrame* aFrame); /* * 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 * return its parent. */ static nsIFrame* GetParentOrPlaceholderFor(nsIFrame* aFrame); /** @@ -1015,32 +1011,32 @@ public: /* * Likewise, but for 'height', 'min-height', or 'max-height'. */ static nscoord ComputeHeightValue(nscoord aContainingBlockHeight, 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()); nscoord result = nsRuleNode::ComputeCoordPercentCalc(aCoord, aContainingBlockHeight); // Clamp calc(), and the subtraction for box-sizing. return std::max(0, result - aContentEdgeToBoxSizingBoxEdge); } static bool IsAutoHeight(const nsStyleCoord &aCoord, nscoord aCBHeight) { 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) { return (aCoord.GetUnit() == eStyleUnit_Coord && aCoord.GetCoordValue() == 0) || (aCoord.GetUnit() == eStyleUnit_Percent && aCoord.GetPercentValue() == 0.0f) || @@ -1063,17 +1059,17 @@ public: /* * Calculate the used values for 'width' and 'height' for a replaced element. * * http://www.w3.org/TR/CSS21/visudet.html#min-max-widths */ 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); /* * Calculate the used values for 'width' and 'height' when width * and height are 'auto'. The tentWidth and tentHeight arguments should be * the result of applying the rules for computing intrinsic sizes and ratios. * as specified by CSS 2.1 sections 10.3.2 and 10.6.2 @@ -1464,36 +1460,16 @@ public: * Some frames with 'position: fixed' (nsStylePosition::mDisplay == * NS_STYLE_POSITION_FIXED) are not really fixed positioned, since * they're inside an element with -moz-transform. This function says * whether such an element is a real fixed-pos element. */ 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 * is, the one that can be obtained with the fewest conversions. * * The flags below can modify the behaviour of this function. The * result is returned as a SurfaceFromElementResult struct, also * defined below. * @@ -1518,19 +1494,17 @@ public: SFE_NO_COLORSPACE_CONVERSION = 1 << 3, /* Whether we should skip premultiplication -- the resulting image will always be an image surface, and must not be given to Thebes for compositing! */ SFE_NO_PREMULTIPLY_ALPHA = 1 << 4 }; 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; /* The size of the surface */ gfxIntSize mSize; /* The principal associated with the element whose surface was returned. If there is a surface, this will never be null. */ nsCOMPtr<nsIPrincipal> mPrincipal; @@ -1581,21 +1555,17 @@ public: */ static nsIContent* GetEditableRootContentByContentEditable(nsIDocument* aDocument); /** * 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 * to the list aFontFaceList. */ static nsresult GetFontFacesForFrames(nsIFrame* aFrame, nsFontFaceList* aFontFaceList); @@ -1675,25 +1645,16 @@ public: /** * Unions the overflow areas of all non-popup children of aFrame with * aOverflowAreas. */ 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 * smaller than 1. */ static float FontSizeInflationFor(const nsIFrame *aFrame); /** * Perform the first half of the computation of FontSizeInflationFor @@ -1895,165 +1856,26 @@ public: * Determine if aImageFrame (which is an nsImageFrame, nsImageControlFrame, or * nsSVGImageFrame) is visible or close to being visible via scrolling and * update the presshell with this knowledge. */ static void 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; static int32_t sFontSizeInflationMappingIntercept; static uint32_t sFontSizeInflationMaxRatio; static bool sFontSizeInflationForceEnabled; static bool sFontSizeInflationDisabledInMasterProcess; 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, CoordType& aClosestXDistance, CoordType& aClosestYDistance) { CoordType fromLeft = aPoint.x - aRect.x; CoordType fromRight = aPoint.x - aRect.XMost(); @@ -2096,38 +1918,19 @@ namespace mozilla { /** * An RAII class which will, for the duration of its lifetime, * **if** the frame given is a container for font size inflation, * set the current inflation container on the pres context to null * (and then, in its destructor, restore the old value). */ 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; }; } } @@ -2152,23 +1955,9 @@ public: nsUnsetAttrRunnable(nsIContent* aContent, nsIAtom* aAttrName); NS_DECL_NSIRUNNABLE nsCOMPtr<nsIContent> mContent; 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__
--- a/layout/generic/nsFlexContainerFrame.cpp +++ b/layout/generic/nsFlexContainerFrame.cpp @@ -1111,21 +1111,21 @@ NS_NewFlexContainerFrame(nsIPresShell* a nsFlexContainerFrame::~nsFlexContainerFrame() { } 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; } /* virtual */ nsIAtom* nsFlexContainerFrame::GetType() const { return nsGkAtoms::flexContainerFrame; @@ -1158,17 +1158,17 @@ GetDisplayFlagsForFlexItem(nsIFrame* aFr } void nsFlexContainerFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { NS_ASSERTION( - nsLayoutUtils::IsFrameListSorted<IsOrderLEQWithDOMFallback>(mFrames), + nsIFrame::IsFrameListSorted<IsOrderLEQWithDOMFallback>(mFrames), "Child frames aren't sorted correctly"); DisplayBorderBackgroundOutline(aBuilder, aLists); // Our children are all block-level, so their borders/backgrounds all go on // the BlockBorderBackgrounds list. nsDisplayListSet childLists(aLists, aLists.BlockBorderBackgrounds()); for (nsFrameList::Enumerator e(mFrames); !e.AtEnd(); e.Next()) {
--- a/layout/generic/nsFontInflationData.cpp +++ b/layout/generic/nsFontInflationData.cpp @@ -197,17 +197,17 @@ nsFontInflationData::UpdateWidth(const n "null-ness should match; NearestCommonAncestorFirstInFlow" " will crash when passed null"); // Particularly when we're computing for the root BFC, the width of // nca might differ significantly for the width of bfc. nsIFrame *nca = NearestCommonAncestorFirstInFlow(firstInflatableDescendant, lastInflatableDescendant, bfc); - while (!nsLayoutUtils::IsContainerForFontSizeInflation(nca)) { + while (!nca->IsContainerForFontSizeInflation()) { nca = nca->GetParent()->FirstInFlow(); } nscoord newNCAWidth = ComputeDescendantWidth(aReflowState, nca); // See comment above "font.size.inflation.lineThreshold" in // modules/libpref/src/init/all.js . nsIPresShell* presShell = bfc->PresContext()->PresShell();
--- a/layout/generic/nsFrame.cpp +++ b/layout/generic/nsFrame.cpp @@ -3873,17 +3873,17 @@ nsFrame::IntrinsicWidthOffsets(nsRenderi result.hPadding = presContext->DevPixelsToAppUnits(padding.LeftRight()); result.hPctPadding = 0; } } return result; } -/* virtual */ nsIFrame::IntrinsicSize +/* virtual */ IntrinsicSize nsFrame::GetIntrinsicSize() { return IntrinsicSize(); // default is width/height set to eStyleUnit_None } /* virtual */ nsSize nsFrame::GetIntrinsicRatio() {
--- a/layout/generic/nsFrame.h +++ b/layout/generic/nsFrame.h @@ -252,17 +252,17 @@ public: virtual nscoord GetMinWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE; virtual nscoord GetPrefWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE; virtual void AddInlineMinWidth(nsRenderingContext *aRenderingContext, InlineMinWidthData *aData) MOZ_OVERRIDE; virtual void AddInlinePrefWidth(nsRenderingContext *aRenderingContext, 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, nsSize aCBSize, nscoord aAvailableWidth, nsSize aMargin, nsSize aBorder, nsSize aPadding, uint32_t aFlags) MOZ_OVERRIDE; // Compute tight bounds assuming this frame honours its border, background
--- a/layout/generic/nsFrameList.h +++ b/layout/generic/nsFrameList.h @@ -426,20 +426,17 @@ public: inline FrameLinkEnumerator(const nsFrameList& aList, nsIFrame* aPrevFrame); void operator=(const FrameLinkEnumerator& aOther) { NS_PRECONDITION(&List() == &aOther.List(), "Different lists?"); mFrame = aOther.mFrame; mPrev = aOther.mPrev; } - void Next() { - mPrev = mFrame; - Enumerator::Next(); - } + inline void Next(); bool AtEnd() const { return Enumerator::AtEnd(); } nsIFrame* PrevFrame() const { return mPrev; } nsIFrame* NextFrame() const { return mFrame; } protected: nsIFrame* mPrev;
--- a/layout/generic/nsIFrame.h +++ b/layout/generic/nsIFrame.h @@ -28,16 +28,17 @@ #include "nsFrameList.h" #include "mozilla/layout/FrameChildList.h" #include "FramePropertyTable.h" #include "mozilla/TypedEnum.h" #include "nsDirection.h" #include <algorithm> #include "nsITheme.h" #include "gfx3DMatrix.h" +#include "nsLayoutUtils.h" #ifdef ACCESSIBILITY #include "mozilla/a11y/AccTypes.h" #endif /** * New rules of reflow: * 1. you get a WillReflow() followed by a Reflow() followed by a DidReflow() in order @@ -538,16 +539,45 @@ MOZ_END_ENUM_CLASS(nsDidReflowStatus) #define NS_FRAME_OVERFLOW_NONE 0x00000000 // there are no overflow rects; // code relies on this being // the all-zero value #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); + } +}; +} + //---------------------------------------------------------------------- /** * A frame in the layout model. This interface is supported by all frame * objects. * * Frames can have multiple child lists: the default child list * (referred to as the <i>principal</i> child list, and additional named @@ -1704,43 +1734,17 @@ public: IntrinsicWidthOffsetData() : hPadding(0), hBorder(0), hMargin(0) , hPctPadding(0.0f), hPctMargin(0.0f) {} }; 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 * no intrinsic ratio. The intrinsic ratio is the ratio of the * height/width of a box with an intrinsic size or the intrinsic * aspect ratio of a scalable vector image without an intrinsic size. * * Either one of the sides may be zero, indicating a zero or infinite @@ -2958,16 +2962,59 @@ NS_PTR_TO_INT32(frame->Properties().Get( static void AddInPopupStateBitToDescendants(nsIFrame* aFrame); /** * Removes the NS_FRAME_IN_POPUP state bit from aFrame and * all descendant frames (including cross-doc ones), unless * the frame is a popup itself. */ 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; nsIContent* mContent; nsStyleContext* mStyleContext; nsIFrame* mParent; private: nsIFrame* mNextSibling; // doubly-linked list of frames @@ -3138,16 +3185,23 @@ private: mOverflow.mVisualDeltas.mTop); } /** * Returns true if any overflow changed. */ 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) { while (--aIndent >= 0) fputs(" ", out); } void ListTag(FILE* out) const { ListTag(out, this); } @@ -3302,16 +3356,155 @@ inline nsFrameList::FrameLinkEnumerator:: FrameLinkEnumerator(const nsFrameList& aList, nsIFrame* aPrevFrame) : Enumerator(aList) { mPrev = 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 nsIFrame::IsFloating() const { return StyleDisplay()->IsFloating(this); }
--- a/layout/generic/nsImageFrame.cpp +++ b/layout/generic/nsImageFrame.cpp @@ -260,18 +260,18 @@ nsImageFrame::Init(nsIContent* aCon bool nsImageFrame::UpdateIntrinsicSize(imgIContainer* aImage) { NS_PRECONDITION(aImage, "null image"); 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; if (NS_SUCCEEDED(aImage->GetIntrinsicSize(&intrinsicSize))) { // If the image has no intrinsic width, intrinsicSize.width will be -1, and // we can leave mIntrinsicSize.width at its default value of eStyleUnit_None. // Otherwise we use intrinsicSize.width. Height works the same way. if (intrinsicSize.width != -1) @@ -788,17 +788,17 @@ nsImageFrame::GetPrefWidth(nsRenderingCo DISPLAY_PREF_WIDTH(this, result); nsPresContext *presContext = PresContext(); EnsureIntrinsicSizeAndRatio(presContext); // convert from normal twips to scaled twips (printing...) return mIntrinsicSize.width.GetUnit() == eStyleUnit_Coord ? mIntrinsicSize.width.GetCoordValue() : 0; } -/* virtual */ nsIFrame::IntrinsicSize +/* virtual */ IntrinsicSize nsImageFrame::GetIntrinsicSize() { return mIntrinsicSize; } /* virtual */ nsSize nsImageFrame::GetIntrinsicRatio() {
--- a/layout/generic/nsImageFrame.h +++ b/layout/generic/nsImageFrame.h @@ -76,17 +76,17 @@ public: virtual void Init(nsIContent* aContent, nsIFrame* aParent, nsIFrame* aPrevInFlow) MOZ_OVERRIDE; virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, const nsRect& aDirtyRect, 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, const nsHTMLReflowState& aReflowState, nsReflowStatus& aStatus); NS_IMETHOD GetContentForEvent(nsEvent* aEvent, nsIContent** aContent); @@ -281,17 +281,17 @@ private: nsRect SourceRectToDest(const nsIntRect & aRect); nsImageMap* mImageMap; nsCOMPtr<imgINotificationObserver> mListener; nsCOMPtr<imgIContainer> mImage; nsSize mComputedSize; - nsIFrame::IntrinsicSize mIntrinsicSize; + mozilla::IntrinsicSize mIntrinsicSize; nsSize mIntrinsicRatio; bool mDisplayingIcon; bool mFirstFrameComplete; bool mReflowCallbackPosted; static nsIIOService* sIOService;
--- a/layout/generic/nsInlineFrame.cpp +++ b/layout/generic/nsInlineFrame.cpp @@ -127,18 +127,18 @@ nsInlineFrame::IsSelfEmpty() // For special frames, ignore things we know we'll skip in GetSkipSides. // XXXbz should we be doing this for non-special frames too, in a more // general way? // Get the first continuation eagerly, as a performance optimization, to // 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; } return true; } bool nsInlineFrame::IsEmpty() @@ -458,18 +458,17 @@ nsInlineFrame::ReflowFrames(nsPresContex nsLineLayout* lineLayout = aReflowState.mLineLayout; bool inFirstLine = aReflowState.mLineLayout->GetInFirstLine(); RestyleManager* restyleManager = aPresContext->RestyleManager(); bool ltr = (NS_STYLE_DIRECTION_LTR == aReflowState.mStyleVisibility->mDirection); 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; } nscoord availableWidth = aReflowState.availableWidth; NS_ASSERTION(availableWidth != NS_UNCONSTRAINEDSIZE, "should no longer use available widths"); // Subtract off left and right border+padding from availableWidth availableWidth -= leftEdge; @@ -621,32 +620,31 @@ nsInlineFrame::ReflowFrames(nsPresContex // whitespace in an inline element don't affect the line-height. aMetrics.width = lineLayout->EndSpan(this); // Compute final width. // 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; } /* * We want to only apply the end border and padding if we're the last * continuation and either not in an {ib} split or the last part of it. To * be the last continuation we have to be complete (so that we won't get a * next-in-flow) and have no non-fluid continuations on our continuation * chain. */ if (NS_FRAME_IS_COMPLETE(aStatus) && !LastInFlow()->GetNextContinuation() && - !nsLayoutUtils::FrameIsNonLastInIBSplit(this)) { + !FrameIsNonLastInIBSplit()) { aMetrics.width += ltr ? aReflowState.mComputedBorderPadding.right : aReflowState.mComputedBorderPadding.left; } nsRefPtr<nsFontMetrics> fm; float inflation = nsLayoutUtils::FontSizeInflationFor(this); nsLayoutUtils::GetFontMetricsForFrame(this, getter_AddRefs(fm), inflation); aReflowState.rendContext->SetFont(fm); @@ -882,20 +880,20 @@ nsInlineFrame::GetSkipSides(const nsHTML // expensive. So don't bother if we already have the relevant bits set. bool ltr = (NS_STYLE_DIRECTION_LTR == StyleVisibility()->mDirection); int startBit = (1 << (ltr ? NS_SIDE_LEFT : NS_SIDE_RIGHT)); int endBit = (1 << (ltr ? NS_SIDE_RIGHT : NS_SIDE_LEFT)); if (((startBit | endBit) & skip) != (startBit | endBit)) { // 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; } } } return skip; }
--- a/layout/generic/nsLineLayout.cpp +++ b/layout/generic/nsLineLayout.cpp @@ -680,17 +680,17 @@ IsPercentageAware(const nsIFrame* aFrame // width and the containing block's width does not itself depend // on the replaced element's width, then the used value of 'width' // is calculated from the constraint equation used for // block-level, non-replaced elements in normal flow. nsIFrame *f = const_cast<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; } } } return false; @@ -1061,17 +1061,17 @@ nsLineLayout::ApplyStartMargin(PerFrameD bool ltr = (NS_STYLE_DIRECTION_LTR == aReflowState.mStyleVisibility->mDirection); // 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 special sibling annotations // 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) pfd->mMargin.left = 0; else pfd->mMargin.right = 0; } else { @@ -1141,17 +1141,17 @@ nsLineLayout::CanPlaceFrame(PerFrameData * continuation will get destroyed later, so we don't want to drop the * end-margin in that case. * 3) The frame is in an {ib} split and is not the last part. * * However, none of that applies if this is a letter frame (XXXbz why?) */ 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; else pfd->mMargin.left = 0; } } else {
--- a/layout/generic/nsSubDocumentFrame.cpp +++ b/layout/generic/nsSubDocumentFrame.cpp @@ -541,17 +541,17 @@ nsSubDocumentFrame::GetPrefWidth(nsRende result = subDocRoot->GetPrefWidth(aRenderingContext); } else { result = GetIntrinsicWidth(); } return result; } -/* virtual */ nsIFrame::IntrinsicSize +/* virtual */ IntrinsicSize nsSubDocumentFrame::GetIntrinsicSize() { nsIFrame* subDocRoot = ObtainIntrinsicSizeFrame(); if (subDocRoot) { return subDocRoot->GetIntrinsicSize(); } return nsLeafFrame::GetIntrinsicSize(); }
--- a/layout/generic/nsSubDocumentFrame.h +++ b/layout/generic/nsSubDocumentFrame.h @@ -43,17 +43,17 @@ public: nsIFrame* aParent, nsIFrame* aPrevInFlow) MOZ_OVERRIDE; virtual void DestroyFrom(nsIFrame* aDestructRoot) MOZ_OVERRIDE; 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, nsSize aCBSize, nscoord aAvailableWidth, nsSize aMargin, nsSize aBorder, nsSize aPadding, bool aShrinkWrap) MOZ_OVERRIDE; virtual nsSize ComputeSize(nsRenderingContext *aRenderingContext,
--- a/layout/mathml/nsMathMLFrame.h +++ b/layout/mathml/nsMathMLFrame.h @@ -6,18 +6,22 @@ #ifndef nsMathMLFrame_h___ #define nsMathMLFrame_h___ #include "mozilla/Attributes.h" #include "nsFontMetrics.h" #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 { public: // nsIMathMLFrame --- virtual bool
--- a/layout/style/nsAnimationManager.cpp +++ b/layout/style/nsAnimationManager.cpp @@ -9,16 +9,17 @@ #include "nsPresContext.h" #include "nsRuleProcessorData.h" #include "nsStyleSet.h" #include "nsCSSRules.h" #include "nsStyleAnimation.h" #include "nsEventDispatcher.h" #include "nsLayoutUtils.h" +#include "nsIFrame.h" #include <math.h> using namespace mozilla; using namespace mozilla::css; ElementAnimations::ElementAnimations(mozilla::dom::Element *aElement, nsIAtom *aElementProperty, nsAnimationManager *aAnimationManager) : CommonElementAnimationData(aElement, aElementProperty,
--- a/layout/svg/nsSVGOuterSVGFrame.cpp +++ b/layout/svg/nsSVGOuterSVGFrame.cpp @@ -226,17 +226,17 @@ nsSVGOuterSVGFrame::GetPrefWidth(nsRende if (result < 0) { result = nscoord(0); } } return result; } -/* virtual */ nsIFrame::IntrinsicSize +/* virtual */ IntrinsicSize nsSVGOuterSVGFrame::GetIntrinsicSize() { // XXXjwatt Note that here we want to return the CSS width/height if they're // specified and we're embedded inside an nsIObjectLoadingContent. IntrinsicSize intrinsicSize; SVGSVGElement *content = static_cast<SVGSVGElement*>(mContent);
--- a/layout/svg/nsSVGOuterSVGFrame.h +++ b/layout/svg/nsSVGOuterSVGFrame.h @@ -37,17 +37,17 @@ public: "foreignObject(s) still registered!"); } #endif // nsIFrame: 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, nsSize aCBSize, nscoord aAvailableWidth, nsSize aMargin, nsSize aBorder, nsSize aPadding, uint32_t aFlags) MOZ_OVERRIDE; NS_IMETHOD Reflow(nsPresContext* aPresContext,
--- a/layout/svg/nsSVGTextFrame2.cpp +++ b/layout/svg/nsSVGTextFrame2.cpp @@ -35,16 +35,17 @@ #include "nsTextFrame.h" #include "nsTextNode.h" #include "SVGAnimatedNumberList.h" #include "SVGContentUtils.h" #include "SVGLengthList.h" #include "SVGNumberList.h" #include "SVGPathElement.h" #include "SVGTextPathElement.h" +#include "nsLayoutUtils.h" #include <algorithm> #include <cmath> #include <limits> using namespace mozilla; using namespace mozilla::dom; // ============================================================================
--- a/layout/xul/base/src/nsBoxFrame.cpp +++ b/layout/xul/base/src/nsBoxFrame.cpp @@ -57,16 +57,17 @@ #include "nsITheme.h" #include "nsTransform2D.h" #include "nsEventStateManager.h" #include "nsEventDispatcher.h" #include "nsIDOMEvent.h" #include "nsDisplayList.h" #include "mozilla/Preferences.h" #include "nsThemeConstants.h" +#include "nsLayoutUtils.h" #include <algorithm> // Needed for Print Preview #include "nsIURI.h" #include "mozilla/TouchEvents.h" using namespace mozilla; @@ -1905,18 +1906,18 @@ IsBoxOrdinalLEQ(nsIFrame* aFrame1, nsIFrame* aRealFrame2 = nsPlaceholderFrame::GetRealFrameFor(aFrame2); return aRealFrame1->GetOrdinal() <= aRealFrame2->GetOrdinal(); } void nsBoxFrame::CheckBoxOrder() { if (SupportsOrdinalsInChildren() && - !nsLayoutUtils::IsFrameListSorted<IsBoxOrdinalLEQ>(mFrames)) { - nsLayoutUtils::SortFrameList<IsBoxOrdinalLEQ>(mFrames); + !nsIFrame::IsFrameListSorted<IsBoxOrdinalLEQ>(mFrames)) { + nsIFrame::SortFrameList<IsBoxOrdinalLEQ>(mFrames); } } nsresult nsBoxFrame::LayoutChildAt(nsBoxLayoutState& aState, nsIFrame* aBox, const nsRect& aRect) { // get the current rect nsRect oldRect(aBox->GetRect());
--- a/layout/xul/base/src/nsProgressMeterFrame.cpp +++ b/layout/xul/base/src/nsProgressMeterFrame.cpp @@ -16,16 +16,50 @@ #include "nsPresContext.h" #include "nsGkAtoms.h" #include "nsINameSpaceManager.h" #include "nsCOMPtr.h" #include "nsBoxLayoutState.h" #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 // // Creates a new Toolbar frame and returns it // nsIFrame* NS_NewProgressMeterFrame (nsIPresShell* aPresShell, nsStyleContext* aContext) {