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