michael@0: /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: /* michael@0: * base class for rendering objects that can be split across lines, michael@0: * columns, or pages michael@0: */ michael@0: michael@0: #ifndef nsSplittableFrame_h___ michael@0: #define nsSplittableFrame_h___ michael@0: michael@0: #include "mozilla/Attributes.h" michael@0: #include "nsFrame.h" michael@0: michael@0: // Derived class that allows splitting michael@0: class nsSplittableFrame : public nsFrame michael@0: { michael@0: public: michael@0: NS_DECL_FRAMEARENA_HELPERS michael@0: michael@0: virtual void Init(nsIContent* aContent, michael@0: nsIFrame* aParent, michael@0: nsIFrame* aPrevInFlow) MOZ_OVERRIDE; michael@0: michael@0: virtual nsSplittableType GetSplittableType() const MOZ_OVERRIDE; michael@0: michael@0: virtual void DestroyFrom(nsIFrame* aDestructRoot) MOZ_OVERRIDE; michael@0: michael@0: /* michael@0: * Frame continuations can be either fluid or not: michael@0: * Fluid continuations ("in-flows") are the result of line breaking, michael@0: * column breaking, or page breaking. michael@0: * Other (non-fluid) continuations can be the result of BiDi frame splitting. michael@0: * A "flow" is a chain of fluid continuations. michael@0: */ michael@0: michael@0: // Get the previous/next continuation, regardless of its type (fluid or non-fluid). michael@0: virtual nsIFrame* GetPrevContinuation() const MOZ_OVERRIDE; michael@0: virtual nsIFrame* GetNextContinuation() const MOZ_OVERRIDE; michael@0: michael@0: // Set a previous/next non-fluid continuation. michael@0: virtual void SetPrevContinuation(nsIFrame*) MOZ_OVERRIDE; michael@0: virtual void SetNextContinuation(nsIFrame*) MOZ_OVERRIDE; michael@0: michael@0: // Get the first/last continuation for this frame. michael@0: virtual nsIFrame* FirstContinuation() const MOZ_OVERRIDE; michael@0: virtual nsIFrame* LastContinuation() const MOZ_OVERRIDE; michael@0: michael@0: #ifdef DEBUG michael@0: // Can aFrame2 be reached from aFrame1 by following prev/next continuations? michael@0: static bool IsInPrevContinuationChain(nsIFrame* aFrame1, nsIFrame* aFrame2); michael@0: static bool IsInNextContinuationChain(nsIFrame* aFrame1, nsIFrame* aFrame2); michael@0: #endif michael@0: michael@0: // Get the previous/next continuation, only if it is fluid (an "in-flow"). michael@0: nsIFrame* GetPrevInFlow() const; michael@0: nsIFrame* GetNextInFlow() const; michael@0: michael@0: virtual nsIFrame* GetPrevInFlowVirtual() const MOZ_OVERRIDE { return GetPrevInFlow(); } michael@0: virtual nsIFrame* GetNextInFlowVirtual() const MOZ_OVERRIDE { return GetNextInFlow(); } michael@0: michael@0: // Set a previous/next fluid continuation. michael@0: virtual void SetPrevInFlow(nsIFrame*) MOZ_OVERRIDE; michael@0: virtual void SetNextInFlow(nsIFrame*) MOZ_OVERRIDE; michael@0: michael@0: // Get the first/last frame in the current flow. michael@0: virtual nsIFrame* FirstInFlow() const MOZ_OVERRIDE; michael@0: virtual nsIFrame* LastInFlow() const MOZ_OVERRIDE; michael@0: michael@0: // Remove the frame from the flow. Connects the frame's prev-in-flow michael@0: // and its next-in-flow. This should only be called in frame Destroy() methods. michael@0: static void RemoveFromFlow(nsIFrame* aFrame); michael@0: michael@0: protected: michael@0: nsSplittableFrame(nsStyleContext* aContext) : nsFrame(aContext) {} michael@0: michael@0: /** michael@0: * Determine the height consumed by our previous-in-flows. michael@0: * michael@0: * @note (bz) This makes laying out a splittable frame with N in-flows michael@0: * O(N^2)! So, use this function with caution and minimize the number michael@0: * of calls to this method. michael@0: */ michael@0: nscoord GetConsumedHeight() const; michael@0: michael@0: /** michael@0: * Retrieve the effective computed height of this frame, which is the computed michael@0: * height, minus the height consumed by any previous in-flows. michael@0: */ michael@0: nscoord GetEffectiveComputedHeight(const nsHTMLReflowState& aReflowState, michael@0: nscoord aConsumed = NS_INTRINSICSIZE) const; michael@0: michael@0: /** michael@0: * @see nsIFrame::GetLogicalSkipSides() michael@0: * @see nsIFrame::ApplyLogicalSkipSides() michael@0: */ michael@0: virtual int GetLogicalSkipSides(const nsHTMLReflowState* aReflowState = nullptr) const MOZ_OVERRIDE; michael@0: michael@0: #ifdef DEBUG michael@0: virtual void DumpBaseRegressionData(nsPresContext* aPresContext, FILE* out, int32_t aIndent) MOZ_OVERRIDE; michael@0: #endif michael@0: michael@0: nsIFrame* mPrevContinuation; michael@0: nsIFrame* mNextContinuation; michael@0: }; michael@0: michael@0: #endif /* nsSplittableFrame_h___ */