nsInlineFrame.h (7562B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 /* rendering object for CSS display:inline objects */ 8 9 #ifndef nsInlineFrame_h___ 10 #define nsInlineFrame_h___ 11 12 #include "nsContainerFrame.h" 13 14 class nsLineLayout; 15 16 namespace mozilla { 17 class PresShell; 18 } // namespace mozilla 19 20 /** 21 * Inline frame class. 22 * 23 * This class manages a list of child frames that are inline frames. Working 24 * with nsLineLayout, the class will reflow and place inline frames on a line. 25 */ 26 class nsInlineFrame : public nsContainerFrame { 27 public: 28 NS_DECL_QUERYFRAME 29 NS_DECL_FRAMEARENA_HELPERS(nsInlineFrame) 30 31 friend nsInlineFrame* NS_NewInlineFrame(mozilla::PresShell* aPresShell, 32 ComputedStyle* aStyle); 33 34 void BuildDisplayList(nsDisplayListBuilder* aBuilder, 35 const nsDisplayListSet& aLists) override; 36 37 #ifdef ACCESSIBILITY 38 mozilla::a11y::AccType AccessibleType() override; 39 #endif 40 41 #ifdef DEBUG_FRAME_DUMP 42 nsresult GetFrameName(nsAString& aResult) const override; 43 #endif 44 45 void InvalidateFrame(uint32_t aDisplayItemKey = 0, 46 bool aRebuildDisplayItems = true) override; 47 void InvalidateFrameWithRect(const nsRect& aRect, 48 uint32_t aDisplayItemKey = 0, 49 bool aRebuildDisplayItems = true) override; 50 51 bool IsEmpty() override; 52 bool IsSelfEmpty() override; 53 54 nscoord GetCaretBaseline() const override; 55 56 FrameSearchResult PeekOffsetCharacter( 57 bool aForward, int32_t* aOffset, 58 PeekOffsetCharacterOptions aOptions = 59 PeekOffsetCharacterOptions()) override; 60 61 void Destroy(DestroyContext&) override; 62 63 void StealFrame(nsIFrame* aChild) override; 64 65 void AddInlineMinISize(const mozilla::IntrinsicSizeInput& aInput, 66 InlineMinISizeData* aData) override; 67 void AddInlinePrefISize(const mozilla::IntrinsicSizeInput& aInput, 68 InlinePrefISizeData* aData) override; 69 SizeComputationResult ComputeSize( 70 const SizeComputationInput& aSizingInput, mozilla::WritingMode aWM, 71 const mozilla::LogicalSize& aCBSize, nscoord aAvailableISize, 72 const mozilla::LogicalSize& aMargin, 73 const mozilla::LogicalSize& aBorderPadding, 74 const mozilla::StyleSizeOverrides& aSizeOverrides, 75 mozilla::ComputeSizeFlags aFlags) override; 76 nsRect ComputeTightBounds(DrawTarget* aDrawTarget) const override; 77 78 void Reflow(nsPresContext* aPresContext, ReflowOutput& aReflowOutput, 79 const ReflowInput& aReflowInput, 80 nsReflowStatus& aStatus) override; 81 82 nsresult AttributeChanged(int32_t aNameSpaceID, nsAtom* aAttribute, 83 AttrModType aModType) override; 84 85 bool CanContinueTextRun() const override; 86 87 void PullOverflowsFromPrevInFlow() override; 88 89 Maybe<nscoord> GetNaturalBaselineBOffset( 90 mozilla::WritingMode aWM, BaselineSharingGroup aBaselineGroup, 91 BaselineExportContext) const override; 92 bool DrainSelfOverflowList() override; 93 94 /** 95 * Return true if the frame is first visual frame or first continuation 96 */ 97 bool IsFirst() const { 98 // If the frame's bidi visual state is set, return is-first state 99 // else return true if it's the first continuation. 100 return HasAnyStateBits(NS_INLINE_FRAME_BIDI_VISUAL_STATE_IS_SET) 101 ? HasAnyStateBits(NS_INLINE_FRAME_BIDI_VISUAL_IS_FIRST) 102 : !GetPrevInFlow(); 103 } 104 105 /** 106 * Return true if the frame is last visual frame or last continuation. 107 */ 108 bool IsLast() const { 109 // If the frame's bidi visual state is set, return is-last state 110 // else return true if it's the last continuation. 111 return HasAnyStateBits(NS_INLINE_FRAME_BIDI_VISUAL_STATE_IS_SET) 112 ? HasAnyStateBits(NS_INLINE_FRAME_BIDI_VISUAL_IS_LAST) 113 : !GetNextInFlow(); 114 } 115 116 // Restyles the block wrappers around our non-inline-outside kids. 117 // This will only be called when such wrappers in fact exist. 118 void UpdateStyleOfOwnedAnonBoxesForIBSplit( 119 mozilla::ServoRestyleState& aRestyleState); 120 121 protected: 122 // Additional reflow input used during our reflow methods 123 struct InlineReflowInput { 124 nsIFrame* mPrevFrame; 125 nsInlineFrame* mNextInFlow; 126 nsIFrame* mLineContainer; 127 nsLineLayout* mLineLayout; 128 bool mSetParentPointer; // when reflowing child frame first set its 129 // parent frame pointer 130 131 InlineReflowInput() { 132 mPrevFrame = nullptr; 133 mNextInFlow = nullptr; 134 mLineContainer = nullptr; 135 mLineLayout = nullptr; 136 mSetParentPointer = false; 137 } 138 }; 139 140 nsInlineFrame(ComputedStyle* aStyle, nsPresContext* aPresContext, ClassID aID) 141 : nsContainerFrame(aStyle, aPresContext, aID), 142 mBaseline(NS_INTRINSIC_ISIZE_UNKNOWN) {} 143 144 LogicalSides GetLogicalSkipSides() const override; 145 146 void ReflowFrames(nsPresContext* aPresContext, 147 const ReflowInput& aReflowInput, InlineReflowInput& rs, 148 ReflowOutput& aMetrics, nsReflowStatus& aStatus); 149 150 void ReflowInlineFrame(nsPresContext* aPresContext, 151 const ReflowInput& aReflowInput, InlineReflowInput& rs, 152 nsIFrame* aFrame, nsReflowStatus& aStatus); 153 154 // Returns whether there's any frame that PullOneFrame would pull from 155 // aNextInFlow or any of aNextInFlow's next-in-flows. 156 static bool HasFramesToPull(nsInlineFrame* aNextInFlow); 157 158 virtual nsIFrame* PullOneFrame(nsPresContext*, InlineReflowInput&); 159 160 virtual void PushFrames(nsPresContext* aPresContext, nsIFrame* aFromChild, 161 nsIFrame* aPrevSibling, InlineReflowInput& aState); 162 163 private: 164 explicit nsInlineFrame(ComputedStyle* aStyle, nsPresContext* aPresContext) 165 : nsInlineFrame(aStyle, aPresContext, kClassID) {} 166 167 /** 168 * Move any frames on our overflow list to the end of our principal list. 169 * @param aInFirstLine whether we're in a first-line frame. 170 * @return true if there were any overflow frames 171 */ 172 bool DrainSelfOverflowListInternal(bool aInFirstLine); 173 174 protected: 175 nscoord mBaseline; 176 }; 177 178 //---------------------------------------------------------------------- 179 180 /** 181 * Variation on inline-frame used to manage lines for line layout in 182 * special situations (:first-line style in particular). 183 */ 184 class nsFirstLineFrame final : public nsInlineFrame { 185 public: 186 NS_DECL_FRAMEARENA_HELPERS(nsFirstLineFrame) 187 188 friend nsFirstLineFrame* NS_NewFirstLineFrame(mozilla::PresShell* aPresShell, 189 ComputedStyle* aStyle); 190 191 #ifdef DEBUG_FRAME_DUMP 192 nsresult GetFrameName(nsAString& aResult) const override; 193 #endif 194 195 void Reflow(nsPresContext* aPresContext, ReflowOutput& aReflowOutput, 196 const ReflowInput& aReflowInput, 197 nsReflowStatus& aStatus) override; 198 199 void Init(nsIContent* aContent, nsContainerFrame* aParent, 200 nsIFrame* aPrevInFlow) override; 201 void PullOverflowsFromPrevInFlow() override; 202 bool DrainSelfOverflowList() override; 203 204 protected: 205 explicit nsFirstLineFrame(ComputedStyle* aStyle, nsPresContext* aPresContext) 206 : nsInlineFrame(aStyle, aPresContext, kClassID) {} 207 208 nsIFrame* PullOneFrame(nsPresContext*, InlineReflowInput&) override; 209 }; 210 211 #endif /* nsInlineFrame_h___ */