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"
10 #include "nsITableCellLayout.h"
12 #include "nsContainerFrame.h"
13 #include "mozilla/ComputedStyle.h"
14 #include "nsIPercentBSizeObserver.h"
16 #include "nsTableRowFrame.h"
17 #include "mozilla/WritingModes.h"
21 } // namespace mozilla
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.
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
) {}
48 typedef mozilla::WritingMode WritingMode
;
49 typedef mozilla::LogicalSide LogicalSide
;
50 typedef mozilla::LogicalMargin LogicalMargin
;
54 NS_DECL_FRAMEARENA_HELPERS(nsTableCellFrame
)
56 nsIScrollableFrame
* GetScrollTargetFrame() const final
;
58 nsTableRowFrame
* GetTableRowFrame() const {
59 nsIFrame
* parent
= GetParent();
60 MOZ_ASSERT(parent
&& parent
->IsTableRowFrame());
61 return static_cast<nsTableRowFrame
*>(parent
);
64 nsTableFrame
* GetTableFrame() const {
65 return GetTableRowFrame()->GetTableFrame();
68 void Init(nsIContent
* aContent
, nsContainerFrame
* aParent
,
69 nsIFrame
* aPrevInFlow
) override
;
71 void Destroy(DestroyContext
&) override
;
74 mozilla::a11y::AccType
AccessibleType() override
;
77 nsresult
AttributeChanged(int32_t aNameSpaceID
, nsAtom
* aAttribute
,
78 int32_t aModType
) override
;
80 /** @see nsIFrame::DidSetComputedStyle */
81 void DidSetComputedStyle(ComputedStyle
* aOldComputedStyle
) override
;
84 // Our anonymous block frame is the content insertion frame so these
85 // methods should never be called:
86 void AppendFrames(ChildListID aListID
, nsFrameList
&& aFrameList
) override
;
87 void InsertFrames(ChildListID aListID
, nsIFrame
* aPrevFrame
,
88 const nsLineList::iterator
* aPrevFrameLine
,
89 nsFrameList
&& aFrameList
) override
;
90 void RemoveFrame(DestroyContext
&, ChildListID
, nsIFrame
*) override
;
93 nsContainerFrame
* GetContentInsertionFrame() override
{
94 return PrincipalChildList().FirstChild()->GetContentInsertionFrame();
97 nsIFrame
* CellContentFrame() const;
99 nsMargin
GetUsedMargin() const override
;
101 void NotifyPercentBSize(const ReflowInput
& aReflowInput
) override
;
103 bool NeedsToObserve(const ReflowInput
& aReflowInput
) override
;
105 void BuildDisplayList(nsDisplayListBuilder
* aBuilder
,
106 const nsDisplayListSet
& aLists
) override
;
108 virtual void ProcessBorders(nsTableFrame
* aFrame
,
109 nsDisplayListBuilder
* aBuilder
,
110 const nsDisplayListSet
& aLists
);
112 nscoord
GetMinISize(gfxContext
* aRenderingContext
) override
;
113 nscoord
GetPrefISize(gfxContext
* aRenderingContext
) override
;
114 IntrinsicSizeOffsetData
IntrinsicISizeOffsets(
115 nscoord aPercentageBasis
= NS_UNCONSTRAINEDSIZE
) override
;
117 void Reflow(nsPresContext
* aPresContext
, ReflowOutput
& aDesiredSize
,
118 const ReflowInput
& aReflowInput
,
119 nsReflowStatus
& aStatus
) override
;
121 #ifdef DEBUG_FRAME_DUMP
122 nsresult
GetFrameName(nsAString
& aResult
) const override
;
125 void BlockDirAlignChild(mozilla::WritingMode aWM
, nscoord aMaxAscent
);
128 * Get the value of vertical-align adjusted for CSS 2's rules for a
129 * table cell, which means the result is always
130 * StyleVerticalAlignKeyword::{Top,Middle,Bottom,Baseline}.
132 virtual mozilla::StyleVerticalAlignKeyword
GetVerticalAlign() const;
134 bool HasVerticalAlignBaseline() const {
135 return GetVerticalAlign() == mozilla::StyleVerticalAlignKeyword::Baseline
&&
140 * Get the first-line baseline of the cell relative to its block-start border
141 * edge, as if the cell were vertically aligned to the top of the row.
143 nscoord
GetCellBaseline() const;
146 * return the cell's specified row span. this is what was specified in the
147 * content model or in the style info, and is always >= 0.
148 * to get the effective row span (the actual value that applies), use
149 * GetEffectiveRowSpan()
150 * @see nsTableFrame::GetEffectiveRowSpan()
152 int32_t GetRowSpan();
154 // there is no set row index because row index depends on the cell's parent
157 // Return our cell content frame.
158 void AppendDirectlyOwnedAnonBoxes(nsTArray
<OwnedAnonBox
>& aResult
) override
;
160 /*---------------- nsITableCellLayout methods ------------------------*/
163 * return the cell's starting row index (starting at 0 for the first row).
164 * for continued cell frames the row index is that of the cell's first-in-flow
165 * and the column index (starting at 0 for the first column
167 NS_IMETHOD
GetCellIndexes(int32_t& aRowIndex
, int32_t& aColIndex
) override
;
169 /** return the mapped cell's row index (starting at 0 for the first row) */
170 uint32_t RowIndex() const {
171 return static_cast<nsTableRowFrame
*>(GetParent())->GetRowIndex();
175 * return the cell's specified col span. this is what was specified in the
176 * content model or in the style info, and is always >= 1.
177 * to get the effective col span (the actual value that applies), use
178 * GetEffectiveColSpan()
179 * @see nsTableFrame::GetEffectiveColSpan()
181 int32_t GetColSpan();
183 /** return the cell's column index (starting at 0 for the first column) */
184 uint32_t ColIndex() const {
185 // NOTE: We copy this from previous continuations, and we don't ever have
186 // dynamic updates when tables split, so our mColIndex always matches our
187 // first continuation's.
188 MOZ_ASSERT(static_cast<nsTableCellFrame
*>(FirstContinuation())->mColIndex
==
190 "mColIndex out of sync with first continuation");
194 void SetColIndex(int32_t aColIndex
);
196 /** return the available isize given to this frame during its last reflow */
197 inline nscoord
GetPriorAvailISize();
199 /** set the available isize given to this frame during its last reflow */
200 inline void SetPriorAvailISize(nscoord aPriorAvailISize
);
202 /** return the desired size returned by this frame during its last reflow */
203 inline mozilla::LogicalSize
GetDesiredSize();
205 /** set the desired size returned by this frame during its last reflow */
206 inline void SetDesiredSize(const ReflowOutput
& aDesiredSize
);
208 bool GetContentEmpty() const;
209 void SetContentEmpty(bool aContentEmpty
);
211 nsTableCellFrame
* GetNextCell() const {
212 nsIFrame
* sibling
= GetNextSibling();
214 !sibling
|| static_cast<nsTableCellFrame
*>(do_QueryFrame(sibling
)),
215 "How do we have a non-cell sibling?");
216 return static_cast<nsTableCellFrame
*>(sibling
);
219 virtual LogicalMargin
GetBorderWidth(WritingMode aWM
) const;
221 void DecorateForSelection(DrawTarget
* aDrawTarget
, nsPoint aPt
);
223 bool ComputeCustomOverflow(mozilla::OverflowAreas
& aOverflowAreas
) override
;
225 void InvalidateFrame(uint32_t aDisplayItemKey
= 0,
226 bool aRebuildDisplayItems
= true) override
;
227 void InvalidateFrameWithRect(const nsRect
& aRect
,
228 uint32_t aDisplayItemKey
= 0,
229 bool aRebuildDisplayItems
= true) override
;
230 void InvalidateFrameForRemoval() override
{ InvalidateFrameSubtree(); }
232 bool ShouldPaintBordersAndBackgrounds() const;
234 bool ShouldPaintBackground(nsDisplayListBuilder
* aBuilder
);
237 nsTableCellFrame(ComputedStyle
* aStyle
, nsTableFrame
* aTableFrame
,
241 LogicalSides
GetLogicalSkipSides() const override
;
244 * GetBorderOverflow says how far the cell's own borders extend
245 * outside its own bounds. In the separated borders model this should
246 * just be zero (as it is for most frames), but in the collapsed
247 * borders model (for which nsBCTableCellFrame overrides this virtual
248 * method), it considers the extents of the collapsed border.
250 virtual nsMargin
GetBorderOverflow();
252 friend class nsTableRowFrame
;
254 uint32_t mColIndex
; // the starting column for this cell
256 nscoord mPriorAvailISize
; // the avail isize during the last reflow
257 mozilla::LogicalSize mDesiredSize
; // the last desired inline and block size
260 inline nscoord
nsTableCellFrame::GetPriorAvailISize() {
261 return mPriorAvailISize
;
264 inline void nsTableCellFrame::SetPriorAvailISize(nscoord aPriorAvailISize
) {
265 mPriorAvailISize
= aPriorAvailISize
;
268 inline mozilla::LogicalSize
nsTableCellFrame::GetDesiredSize() {
272 inline void nsTableCellFrame::SetDesiredSize(const ReflowOutput
& aDesiredSize
) {
273 mDesiredSize
= aDesiredSize
.Size(GetWritingMode());
276 inline bool nsTableCellFrame::GetContentEmpty() const {
277 return HasAnyStateBits(NS_TABLE_CELL_CONTENT_EMPTY
);
280 inline void nsTableCellFrame::SetContentEmpty(bool aContentEmpty
) {
282 AddStateBits(NS_TABLE_CELL_CONTENT_EMPTY
);
284 RemoveStateBits(NS_TABLE_CELL_CONTENT_EMPTY
);
288 // nsBCTableCellFrame
289 class nsBCTableCellFrame final
: public nsTableCellFrame
{
290 typedef mozilla::image::ImgDrawResult ImgDrawResult
;
293 NS_DECL_FRAMEARENA_HELPERS(nsBCTableCellFrame
)
295 nsBCTableCellFrame(ComputedStyle
* aStyle
, nsTableFrame
* aTableFrame
);
297 ~nsBCTableCellFrame();
299 nsMargin
GetUsedBorder() const override
;
301 // Get the *inner half of the border only*, in twips.
302 LogicalMargin
GetBorderWidth(WritingMode aWM
) const override
;
304 // Get the *inner half of the border only*, in pixels.
305 BCPixelSize
GetBorderWidth(LogicalSide aSide
) const;
307 // Set the full (both halves) width of the border
308 void SetBorderWidth(LogicalSide aSide
, BCPixelSize aPixelValue
);
310 nsMargin
GetBorderOverflow() override
;
312 #ifdef DEBUG_FRAME_DUMP
313 nsresult
GetFrameName(nsAString
& aResult
) const override
;
317 // These are the entire width of the border (the cell edge contains only
319 BCPixelSize mBStartBorder
;
320 BCPixelSize mIEndBorder
;
321 BCPixelSize mBEndBorder
;
322 BCPixelSize mIStartBorder
;
325 // Implemented here because that's a sane-ish way to make the includes work out.
326 inline nsTableCellFrame
* nsTableRowFrame::GetFirstCell() const {
327 nsIFrame
* firstChild
= mFrames
.FirstChild();
329 !firstChild
|| static_cast<nsTableCellFrame
*>(do_QueryFrame(firstChild
)),
330 "How do we have a non-cell child?");
331 return static_cast<nsTableCellFrame
*>(firstChild
);