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 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
;
72 mozilla::a11y::AccType
AccessibleType() override
;
75 nsresult
AttributeChanged(int32_t aNameSpaceID
, nsAtom
* aAttribute
,
76 int32_t aModType
) override
;
78 /** @see nsIFrame::DidSetComputedStyle */
79 void DidSetComputedStyle(ComputedStyle
* aOldComputedStyle
) override
;
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
;
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
;
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
&&
135 bool CellHasVisibleContent(nscoord aBSize
, nsTableFrame
* tableFrame
,
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
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
==
189 "mColIndex out of sync with first continuation");
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();
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
);
236 nsTableCellFrame(ComputedStyle
* aStyle
, nsTableFrame
* aTableFrame
,
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() {
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
) {
281 AddStateBits(NS_TABLE_CELL_CONTENT_EMPTY
);
283 RemoveStateBits(NS_TABLE_CELL_CONTENT_EMPTY
);
287 // nsBCTableCellFrame
288 class nsBCTableCellFrame final
: public nsTableCellFrame
{
289 typedef mozilla::image::ImgDrawResult ImgDrawResult
;
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
;
316 // These are the entire width of the border (the cell edge contains only
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();
328 !firstChild
|| static_cast<nsTableCellFrame
*>(do_QueryFrame(firstChild
)),
329 "How do we have a non-cell child?");
330 return static_cast<nsTableCellFrame
*>(firstChild
);