Bug 1869043 allow a device to be specified with MediaTrackGraph::NotifyWhenDeviceStar...
[gecko.git] / layout / tables / nsTableCellFrame.h
blob6ac33626c07adf1a932b419398d9be27a2885457
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 #ifndef nsTableCellFrame_h__
6 #define nsTableCellFrame_h__
8 #include "mozilla/Attributes.h"
9 #include "celldata.h"
10 #include "nsITableCellLayout.h"
11 #include "nscore.h"
12 #include "nsContainerFrame.h"
13 #include "mozilla/ComputedStyle.h"
14 #include "nsIPercentBSizeObserver.h"
15 #include "nsTArray.h"
16 #include "nsTableRowFrame.h"
17 #include "mozilla/WritingModes.h"
19 namespace mozilla {
20 class PresShell;
21 } // namespace mozilla
23 /**
24 * nsTableCellFrame
25 * data structure to maintain information about a single table cell's frame
27 * NOTE: frames are not ref counted. We expose addref and release here
28 * so we can change that decsion in the future. Users of nsITableCellLayout
29 * should refcount correctly as if this object is being ref counted, though
30 * no actual support is under the hood.
32 * @author sclark
34 class nsTableCellFrame : public nsContainerFrame,
35 public nsITableCellLayout,
36 public nsIPercentBSizeObserver {
37 typedef mozilla::gfx::DrawTarget DrawTarget;
38 typedef mozilla::image::ImgDrawResult ImgDrawResult;
40 friend nsTableCellFrame* NS_NewTableCellFrame(mozilla::PresShell* aPresShell,
41 ComputedStyle* aStyle,
42 nsTableFrame* aTableFrame);
44 nsTableCellFrame(ComputedStyle* aStyle, nsTableFrame* aTableFrame)
45 : nsTableCellFrame(aStyle, aTableFrame, kClassID) {}
47 protected:
48 typedef mozilla::WritingMode WritingMode;
49 typedef mozilla::LogicalSide LogicalSide;
50 typedef mozilla::LogicalMargin LogicalMargin;
52 public:
53 NS_DECL_QUERYFRAME
54 NS_DECL_FRAMEARENA_HELPERS(nsTableCellFrame)
56 nsTableRowFrame* GetTableRowFrame() const {
57 nsIFrame* parent = GetParent();
58 MOZ_ASSERT(parent && parent->IsTableRowFrame());
59 return static_cast<nsTableRowFrame*>(parent);
62 nsTableFrame* GetTableFrame() const {
63 return GetTableRowFrame()->GetTableFrame();
66 void Init(nsIContent* aContent, nsContainerFrame* aParent,
67 nsIFrame* aPrevInFlow) override;
69 void Destroy(DestroyContext&) override;
71 #ifdef ACCESSIBILITY
72 mozilla::a11y::AccType AccessibleType() override;
73 #endif
75 nsresult AttributeChanged(int32_t aNameSpaceID, nsAtom* aAttribute,
76 int32_t aModType) override;
78 /** @see nsIFrame::DidSetComputedStyle */
79 void DidSetComputedStyle(ComputedStyle* aOldComputedStyle) override;
81 #ifdef DEBUG
82 // Our anonymous block frame is the content insertion frame so these
83 // methods should never be called:
84 void AppendFrames(ChildListID aListID, nsFrameList&& aFrameList) override;
85 void InsertFrames(ChildListID aListID, nsIFrame* aPrevFrame,
86 const nsLineList::iterator* aPrevFrameLine,
87 nsFrameList&& aFrameList) override;
88 void RemoveFrame(DestroyContext&, ChildListID, nsIFrame*) override;
89 #endif
91 nsContainerFrame* GetContentInsertionFrame() override {
92 return PrincipalChildList().FirstChild()->GetContentInsertionFrame();
95 nsMargin GetUsedMargin() const override;
97 void NotifyPercentBSize(const ReflowInput& aReflowInput) override;
99 bool NeedsToObserve(const ReflowInput& aReflowInput) override;
101 void BuildDisplayList(nsDisplayListBuilder* aBuilder,
102 const nsDisplayListSet& aLists) override;
104 virtual void ProcessBorders(nsTableFrame* aFrame,
105 nsDisplayListBuilder* aBuilder,
106 const nsDisplayListSet& aLists);
108 nscoord GetMinISize(gfxContext* aRenderingContext) override;
109 nscoord GetPrefISize(gfxContext* aRenderingContext) override;
110 IntrinsicSizeOffsetData IntrinsicISizeOffsets(
111 nscoord aPercentageBasis = NS_UNCONSTRAINEDSIZE) override;
113 void Reflow(nsPresContext* aPresContext, ReflowOutput& aDesiredSize,
114 const ReflowInput& aReflowInput,
115 nsReflowStatus& aStatus) override;
117 #ifdef DEBUG_FRAME_DUMP
118 nsresult GetFrameName(nsAString& aResult) const override;
119 #endif
121 void BlockDirAlignChild(mozilla::WritingMode aWM, nscoord aMaxAscent);
124 * Get the value of vertical-align adjusted for CSS 2's rules for a
125 * table cell, which means the result is always
126 * StyleVerticalAlignKeyword::{Top,Middle,Bottom,Baseline}.
128 virtual mozilla::StyleVerticalAlignKeyword GetVerticalAlign() const;
130 bool HasVerticalAlignBaseline() const {
131 return GetVerticalAlign() == mozilla::StyleVerticalAlignKeyword::Baseline &&
132 !GetContentEmpty();
135 bool CellHasVisibleContent(nscoord aBSize, nsTableFrame* tableFrame,
136 nsIFrame* kidFrame);
139 * Get the first-line baseline of the cell relative to its block-start border
140 * edge, as if the cell were vertically aligned to the top of the row.
142 nscoord GetCellBaseline() const;
145 * return the cell's specified row span. this is what was specified in the
146 * content model or in the style info, and is always >= 0.
147 * to get the effective row span (the actual value that applies), use
148 * GetEffectiveRowSpan()
149 * @see nsTableFrame::GetEffectiveRowSpan()
151 int32_t GetRowSpan();
153 // there is no set row index because row index depends on the cell's parent
154 // row only
156 // Return our cell content frame.
157 void AppendDirectlyOwnedAnonBoxes(nsTArray<OwnedAnonBox>& aResult) override;
159 /*---------------- nsITableCellLayout methods ------------------------*/
162 * return the cell's starting row index (starting at 0 for the first row).
163 * for continued cell frames the row index is that of the cell's first-in-flow
164 * and the column index (starting at 0 for the first column
166 NS_IMETHOD GetCellIndexes(int32_t& aRowIndex, int32_t& aColIndex) override;
168 /** return the mapped cell's row index (starting at 0 for the first row) */
169 uint32_t RowIndex() const {
170 return static_cast<nsTableRowFrame*>(GetParent())->GetRowIndex();
174 * return the cell's specified col span. this is what was specified in the
175 * content model or in the style info, and is always >= 1.
176 * to get the effective col span (the actual value that applies), use
177 * GetEffectiveColSpan()
178 * @see nsTableFrame::GetEffectiveColSpan()
180 int32_t GetColSpan();
182 /** return the cell's column index (starting at 0 for the first column) */
183 uint32_t ColIndex() const {
184 // NOTE: We copy this from previous continuations, and we don't ever have
185 // dynamic updates when tables split, so our mColIndex always matches our
186 // first continuation's.
187 MOZ_ASSERT(static_cast<nsTableCellFrame*>(FirstContinuation())->mColIndex ==
188 mColIndex,
189 "mColIndex out of sync with first continuation");
190 return mColIndex;
193 void SetColIndex(int32_t aColIndex);
195 /** return the available isize given to this frame during its last reflow */
196 inline nscoord GetPriorAvailISize();
198 /** set the available isize given to this frame during its last reflow */
199 inline void SetPriorAvailISize(nscoord aPriorAvailISize);
201 /** return the desired size returned by this frame during its last reflow */
202 inline mozilla::LogicalSize GetDesiredSize();
204 /** set the desired size returned by this frame during its last reflow */
205 inline void SetDesiredSize(const ReflowOutput& aDesiredSize);
207 bool GetContentEmpty() const;
208 void SetContentEmpty(bool aContentEmpty);
210 nsTableCellFrame* GetNextCell() const {
211 nsIFrame* sibling = GetNextSibling();
212 MOZ_ASSERT(
213 !sibling || static_cast<nsTableCellFrame*>(do_QueryFrame(sibling)),
214 "How do we have a non-cell sibling?");
215 return static_cast<nsTableCellFrame*>(sibling);
218 virtual LogicalMargin GetBorderWidth(WritingMode aWM) const;
220 void DecorateForSelection(DrawTarget* aDrawTarget, nsPoint aPt);
222 bool ComputeCustomOverflow(mozilla::OverflowAreas& aOverflowAreas) override;
224 void InvalidateFrame(uint32_t aDisplayItemKey = 0,
225 bool aRebuildDisplayItems = true) override;
226 void InvalidateFrameWithRect(const nsRect& aRect,
227 uint32_t aDisplayItemKey = 0,
228 bool aRebuildDisplayItems = true) override;
229 void InvalidateFrameForRemoval() override { InvalidateFrameSubtree(); }
231 bool ShouldPaintBordersAndBackgrounds() const;
233 bool ShouldPaintBackground(nsDisplayListBuilder* aBuilder);
235 protected:
236 nsTableCellFrame(ComputedStyle* aStyle, nsTableFrame* aTableFrame,
237 ClassID aID);
238 ~nsTableCellFrame();
240 LogicalSides GetLogicalSkipSides() const override;
243 * GetBorderOverflow says how far the cell's own borders extend
244 * outside its own bounds. In the separated borders model this should
245 * just be zero (as it is for most frames), but in the collapsed
246 * borders model (for which nsBCTableCellFrame overrides this virtual
247 * method), it considers the extents of the collapsed border.
249 virtual nsMargin GetBorderOverflow();
251 friend class nsTableRowFrame;
253 uint32_t mColIndex; // the starting column for this cell
255 nscoord mPriorAvailISize; // the avail isize during the last reflow
256 mozilla::LogicalSize mDesiredSize; // the last desired inline and block size
259 inline nscoord nsTableCellFrame::GetPriorAvailISize() {
260 return mPriorAvailISize;
263 inline void nsTableCellFrame::SetPriorAvailISize(nscoord aPriorAvailISize) {
264 mPriorAvailISize = aPriorAvailISize;
267 inline mozilla::LogicalSize nsTableCellFrame::GetDesiredSize() {
268 return mDesiredSize;
271 inline void nsTableCellFrame::SetDesiredSize(const ReflowOutput& aDesiredSize) {
272 mDesiredSize = aDesiredSize.Size(GetWritingMode());
275 inline bool nsTableCellFrame::GetContentEmpty() const {
276 return HasAnyStateBits(NS_TABLE_CELL_CONTENT_EMPTY);
279 inline void nsTableCellFrame::SetContentEmpty(bool aContentEmpty) {
280 if (aContentEmpty) {
281 AddStateBits(NS_TABLE_CELL_CONTENT_EMPTY);
282 } else {
283 RemoveStateBits(NS_TABLE_CELL_CONTENT_EMPTY);
287 // nsBCTableCellFrame
288 class nsBCTableCellFrame final : public nsTableCellFrame {
289 typedef mozilla::image::ImgDrawResult ImgDrawResult;
291 public:
292 NS_DECL_FRAMEARENA_HELPERS(nsBCTableCellFrame)
294 nsBCTableCellFrame(ComputedStyle* aStyle, nsTableFrame* aTableFrame);
296 ~nsBCTableCellFrame();
298 nsMargin GetUsedBorder() const override;
300 // Get the *inner half of the border only*, in twips.
301 LogicalMargin GetBorderWidth(WritingMode aWM) const override;
303 // Get the *inner half of the border only*, in pixels.
304 BCPixelSize GetBorderWidth(LogicalSide aSide) const;
306 // Set the full (both halves) width of the border
307 void SetBorderWidth(LogicalSide aSide, BCPixelSize aPixelValue);
309 nsMargin GetBorderOverflow() override;
311 #ifdef DEBUG_FRAME_DUMP
312 nsresult GetFrameName(nsAString& aResult) const override;
313 #endif
315 private:
316 // These are the entire width of the border (the cell edge contains only
317 // the inner half).
318 BCPixelSize mBStartBorder;
319 BCPixelSize mIEndBorder;
320 BCPixelSize mBEndBorder;
321 BCPixelSize mIStartBorder;
324 // Implemented here because that's a sane-ish way to make the includes work out.
325 inline nsTableCellFrame* nsTableRowFrame::GetFirstCell() const {
326 nsIFrame* firstChild = mFrames.FirstChild();
327 MOZ_ASSERT(
328 !firstChild || static_cast<nsTableCellFrame*>(do_QueryFrame(firstChild)),
329 "How do we have a non-cell child?");
330 return static_cast<nsTableCellFrame*>(firstChild);
333 #endif