diff options
Diffstat (limited to 'layout/generic/nsInlineFrame.h')
-rw-r--r-- | layout/generic/nsInlineFrame.h | 217 |
1 files changed, 217 insertions, 0 deletions
diff --git a/layout/generic/nsInlineFrame.h b/layout/generic/nsInlineFrame.h new file mode 100644 index 0000000000..77da4618e4 --- /dev/null +++ b/layout/generic/nsInlineFrame.h @@ -0,0 +1,217 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* 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/. */ + +/* rendering object for CSS display:inline objects */ + +#ifndef nsInlineFrame_h___ +#define nsInlineFrame_h___ + +#include "mozilla/Attributes.h" +#include "nsContainerFrame.h" + +class nsLineLayout; + +namespace mozilla { +class PresShell; +} // namespace mozilla + +/** + * Inline frame class. + * + * This class manages a list of child frames that are inline frames. Working + * with nsLineLayout, the class will reflow and place inline frames on a line. + */ +class nsInlineFrame : public nsContainerFrame { + public: + NS_DECL_QUERYFRAME + NS_DECL_FRAMEARENA_HELPERS(nsInlineFrame) + + friend nsInlineFrame* NS_NewInlineFrame(mozilla::PresShell* aPresShell, + ComputedStyle* aStyle); + + // nsIFrame overrides + virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsDisplayListSet& aLists) override; + +#ifdef ACCESSIBILITY + virtual mozilla::a11y::AccType AccessibleType() override; +#endif + +#ifdef DEBUG_FRAME_DUMP + virtual nsresult GetFrameName(nsAString& aResult) const override; +#endif + + virtual bool IsFrameOfType(uint32_t aFlags) const override { + if (aFlags & (eSupportsCSSTransforms | eSupportsContainLayoutAndPaint)) { + return false; + } + return nsContainerFrame::IsFrameOfType( + aFlags & + ~(nsIFrame::eBidiInlineContainer | nsIFrame::eLineParticipant)); + } + + virtual void InvalidateFrame(uint32_t aDisplayItemKey = 0, + bool aRebuildDisplayItems = true) override; + virtual void InvalidateFrameWithRect( + const nsRect& aRect, uint32_t aDisplayItemKey = 0, + bool aRebuildDisplayItems = true) override; + + virtual bool IsEmpty() override; + virtual bool IsSelfEmpty() override; + + virtual FrameSearchResult PeekOffsetCharacter( + bool aForward, int32_t* aOffset, + PeekOffsetCharacterOptions aOptions = + PeekOffsetCharacterOptions()) override; + + virtual void DestroyFrom(nsIFrame* aDestructRoot, + PostDestroyData& aPostDestroyData) override; + void StealFrame(nsIFrame* aChild) override; + + // nsIHTMLReflow overrides + virtual void AddInlineMinISize(gfxContext* aRenderingContext, + InlineMinISizeData* aData) override; + virtual void AddInlinePrefISize(gfxContext* aRenderingContext, + InlinePrefISizeData* aData) override; + SizeComputationResult ComputeSize(gfxContext* aRenderingContext, + mozilla::WritingMode aWM, + const mozilla::LogicalSize& aCBSize, + nscoord aAvailableISize, + const mozilla::LogicalSize& aMargin, + const mozilla::LogicalSize& aBorderPadding, + mozilla::ComputeSizeFlags aFlags) override; + virtual nsRect ComputeTightBounds(DrawTarget* aDrawTarget) const override; + virtual void Reflow(nsPresContext* aPresContext, ReflowOutput& aDesiredSize, + const ReflowInput& aReflowInput, + nsReflowStatus& aStatus) override; + + virtual nsresult AttributeChanged(int32_t aNameSpaceID, nsAtom* aAttribute, + int32_t aModType) override; + + virtual bool CanContinueTextRun() const override; + + virtual void PullOverflowsFromPrevInFlow() override; + virtual nscoord GetLogicalBaseline( + mozilla::WritingMode aWritingMode) const override; + virtual bool DrainSelfOverflowList() override; + + /** + * Return true if the frame is first visual frame or first continuation + */ + bool IsFirst() const { + // If the frame's bidi visual state is set, return is-first state + // else return true if it's the first continuation. + return HasAnyStateBits(NS_INLINE_FRAME_BIDI_VISUAL_STATE_IS_SET) + ? HasAnyStateBits(NS_INLINE_FRAME_BIDI_VISUAL_IS_FIRST) + : !GetPrevInFlow(); + } + + /** + * Return true if the frame is last visual frame or last continuation. + */ + bool IsLast() const { + // If the frame's bidi visual state is set, return is-last state + // else return true if it's the last continuation. + return HasAnyStateBits(NS_INLINE_FRAME_BIDI_VISUAL_STATE_IS_SET) + ? HasAnyStateBits(NS_INLINE_FRAME_BIDI_VISUAL_IS_LAST) + : !GetNextInFlow(); + } + + // Restyles the block wrappers around our non-inline-outside kids. + // This will only be called when such wrappers in fact exist. + void UpdateStyleOfOwnedAnonBoxesForIBSplit( + mozilla::ServoRestyleState& aRestyleState); + + protected: + // Additional reflow input used during our reflow methods + struct InlineReflowInput { + nsIFrame* mPrevFrame; + nsInlineFrame* mNextInFlow; + nsIFrame* mLineContainer; + nsLineLayout* mLineLayout; + bool mSetParentPointer; // when reflowing child frame first set its + // parent frame pointer + + InlineReflowInput() { + mPrevFrame = nullptr; + mNextInFlow = nullptr; + mLineContainer = nullptr; + mLineLayout = nullptr; + mSetParentPointer = false; + } + }; + + nsInlineFrame(ComputedStyle* aStyle, nsPresContext* aPresContext, ClassID aID) + : nsContainerFrame(aStyle, aPresContext, aID), + mBaseline(NS_INTRINSIC_ISIZE_UNKNOWN) {} + + LogicalSides GetLogicalSkipSides() const override; + + void ReflowFrames(nsPresContext* aPresContext, + const ReflowInput& aReflowInput, InlineReflowInput& rs, + ReflowOutput& aMetrics, nsReflowStatus& aStatus); + + void ReflowInlineFrame(nsPresContext* aPresContext, + const ReflowInput& aReflowInput, InlineReflowInput& rs, + nsIFrame* aFrame, nsReflowStatus& aStatus); + + // Returns whether there's any frame that PullOneFrame would pull from + // aNextInFlow or any of aNextInFlow's next-in-flows. + static bool HasFramesToPull(nsInlineFrame* aNextInFlow); + + virtual nsIFrame* PullOneFrame(nsPresContext*, InlineReflowInput&); + + virtual void PushFrames(nsPresContext* aPresContext, nsIFrame* aFromChild, + nsIFrame* aPrevSibling, InlineReflowInput& aState); + + private: + explicit nsInlineFrame(ComputedStyle* aStyle, nsPresContext* aPresContext) + : nsInlineFrame(aStyle, aPresContext, kClassID) {} + + /** + * Move any frames on our overflow list to the end of our principal list. + * @param aInFirstLine whether we're in a first-line frame. + * @return true if there were any overflow frames + */ + bool DrainSelfOverflowListInternal(bool aInFirstLine); + + protected: + nscoord mBaseline; +}; + +//---------------------------------------------------------------------- + +/** + * Variation on inline-frame used to manage lines for line layout in + * special situations (:first-line style in particular). + */ +class nsFirstLineFrame final : public nsInlineFrame { + public: + NS_DECL_FRAMEARENA_HELPERS(nsFirstLineFrame) + + friend nsFirstLineFrame* NS_NewFirstLineFrame(mozilla::PresShell* aPresShell, + ComputedStyle* aStyle); + +#ifdef DEBUG_FRAME_DUMP + virtual nsresult GetFrameName(nsAString& aResult) const override; +#endif + virtual void Reflow(nsPresContext* aPresContext, ReflowOutput& aDesiredSize, + const ReflowInput& aReflowInput, + nsReflowStatus& aStatus) override; + + virtual void Init(nsIContent* aContent, nsContainerFrame* aParent, + nsIFrame* aPrevInFlow) override; + virtual void PullOverflowsFromPrevInFlow() override; + virtual bool DrainSelfOverflowList() override; + + protected: + explicit nsFirstLineFrame(ComputedStyle* aStyle, nsPresContext* aPresContext) + : nsInlineFrame(aStyle, aPresContext, kClassID) {} + + nsIFrame* PullOneFrame(nsPresContext*, InlineReflowInput&) override; +}; + +#endif /* nsInlineFrame_h___ */ |