Line data Source code
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__
7 :
8 : #include "mozilla/Attributes.h"
9 : #include "celldata.h"
10 : #include "imgIContainer.h"
11 : #include "nsITableCellLayout.h"
12 : #include "nscore.h"
13 : #include "nsContainerFrame.h"
14 : #include "nsStyleContext.h"
15 : #include "nsIPercentBSizeObserver.h"
16 : #include "nsGkAtoms.h"
17 : #include "nsLayoutUtils.h"
18 : #include "nsTArray.h"
19 : #include "nsTableRowFrame.h"
20 : #include "mozilla/WritingModes.h"
21 :
22 : /**
23 : * nsTableCellFrame
24 : * data structure to maintain information about a single table cell's frame
25 : *
26 : * NOTE: frames are not ref counted. We expose addref and release here
27 : * so we can change that decsion in the future. Users of nsITableCellLayout
28 : * should refcount correctly as if this object is being ref counted, though
29 : * no actual support is under the hood.
30 : *
31 : * @author sclark
32 : */
33 : class nsTableCellFrame : public nsContainerFrame,
34 : public nsITableCellLayout,
35 : public nsIPercentBSizeObserver
36 : {
37 : typedef mozilla::gfx::DrawTarget DrawTarget;
38 : typedef mozilla::image::DrawResult DrawResult;
39 :
40 : friend nsTableCellFrame* NS_NewTableCellFrame(nsIPresShell* aPresShell,
41 : nsStyleContext* aContext,
42 : nsTableFrame* aTableFrame);
43 :
44 0 : nsTableCellFrame(nsStyleContext* aContext, nsTableFrame* aTableFrame)
45 0 : : nsTableCellFrame(aContext, aTableFrame, kClassID) {}
46 :
47 : protected:
48 : typedef mozilla::WritingMode WritingMode;
49 : typedef mozilla::LogicalSide LogicalSide;
50 : typedef mozilla::LogicalMargin LogicalMargin;
51 :
52 : public:
53 : NS_DECL_QUERYFRAME
54 0 : NS_DECL_FRAMEARENA_HELPERS(nsTableCellFrame)
55 :
56 0 : nsTableRowFrame* GetTableRowFrame() const
57 : {
58 0 : nsIFrame* parent = GetParent();
59 0 : MOZ_ASSERT(parent && parent->IsTableRowFrame());
60 0 : return static_cast<nsTableRowFrame*>(parent);
61 : }
62 :
63 0 : nsTableFrame* GetTableFrame() const
64 : {
65 0 : return GetTableRowFrame()->GetTableFrame();
66 : }
67 :
68 : virtual void Init(nsIContent* aContent,
69 : nsContainerFrame* aParent,
70 : nsIFrame* aPrevInFlow) override;
71 :
72 : virtual void DestroyFrom(nsIFrame* aDestructRoot) override;
73 :
74 : #ifdef ACCESSIBILITY
75 : virtual mozilla::a11y::AccType AccessibleType() override;
76 : #endif
77 :
78 : virtual nsresult AttributeChanged(int32_t aNameSpaceID,
79 : nsIAtom* aAttribute,
80 : int32_t aModType) override;
81 :
82 : /** @see nsIFrame::DidSetStyleContext */
83 : virtual void DidSetStyleContext(nsStyleContext* aOldStyleContext) override;
84 :
85 : #ifdef DEBUG
86 : // Our anonymous block frame is the content insertion frame so these
87 : // methods should never be called:
88 : virtual void AppendFrames(ChildListID aListID,
89 : nsFrameList& aFrameList) override;
90 : virtual void InsertFrames(ChildListID aListID,
91 : nsIFrame* aPrevFrame,
92 : nsFrameList& aFrameList) override;
93 : virtual void RemoveFrame(ChildListID aListID,
94 : nsIFrame* aOldFrame) override;
95 : #endif
96 :
97 0 : virtual nsContainerFrame* GetContentInsertionFrame() override {
98 0 : return PrincipalChildList().FirstChild()->GetContentInsertionFrame();
99 : }
100 :
101 : virtual nsMargin GetUsedMargin() const override;
102 :
103 : virtual void NotifyPercentBSize(const ReflowInput& aReflowInput) override;
104 :
105 : virtual bool NeedsToObserve(const ReflowInput& aReflowInput) override;
106 :
107 : virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder,
108 : const nsRect& aDirtyRect,
109 : const nsDisplayListSet& aLists) override;
110 :
111 : virtual nsresult ProcessBorders(nsTableFrame* aFrame,
112 : nsDisplayListBuilder* aBuilder,
113 : const nsDisplayListSet& aLists);
114 :
115 : virtual nscoord GetMinISize(gfxContext *aRenderingContext) override;
116 : virtual nscoord GetPrefISize(gfxContext *aRenderingContext) override;
117 : virtual IntrinsicISizeOffsetData IntrinsicISizeOffsets() override;
118 :
119 : virtual void Reflow(nsPresContext* aPresContext,
120 : ReflowOutput& aDesiredSize,
121 : const ReflowInput& aReflowInput,
122 : nsReflowStatus& aStatus) override;
123 :
124 : #ifdef DEBUG_FRAME_DUMP
125 : virtual nsresult GetFrameName(nsAString& aResult) const override;
126 : #endif
127 :
128 : void BlockDirAlignChild(mozilla::WritingMode aWM, nscoord aMaxAscent);
129 :
130 : /*
131 : * Get the value of vertical-align adjusted for CSS 2's rules for a
132 : * table cell, which means the result is always
133 : * NS_STYLE_VERTICAL_ALIGN_{TOP,MIDDLE,BOTTOM,BASELINE}.
134 : */
135 : virtual uint8_t GetVerticalAlign() const;
136 :
137 0 : bool HasVerticalAlignBaseline() const {
138 0 : return GetVerticalAlign() == NS_STYLE_VERTICAL_ALIGN_BASELINE;
139 : }
140 :
141 : bool CellHasVisibleContent(nscoord aBSize,
142 : nsTableFrame* tableFrame,
143 : nsIFrame* kidFrame);
144 :
145 : /**
146 : * Get the first-line baseline of the cell relative to its block-start border
147 : * edge, as if the cell were vertically aligned to the top of the row.
148 : */
149 : nscoord GetCellBaseline() const;
150 :
151 : /**
152 : * return the cell's specified row span. this is what was specified in the
153 : * content model or in the style info, and is always >= 0.
154 : * to get the effective row span (the actual value that applies), use GetEffectiveRowSpan()
155 : * @see nsTableFrame::GetEffectiveRowSpan()
156 : */
157 : int32_t GetRowSpan();
158 :
159 : // there is no set row index because row index depends on the cell's parent row only
160 :
161 : // Return our cell content frame.
162 : void AppendDirectlyOwnedAnonBoxes(nsTArray<OwnedAnonBox>& aResult) override;
163 :
164 : /*---------------- nsITableCellLayout methods ------------------------*/
165 :
166 : /**
167 : * return the cell's starting row index (starting at 0 for the first row).
168 : * for continued cell frames the row index is that of the cell's first-in-flow
169 : * and the column index (starting at 0 for the first column
170 : */
171 : NS_IMETHOD GetCellIndexes(int32_t &aRowIndex, int32_t &aColIndex) override;
172 :
173 : /** return the mapped cell's row index (starting at 0 for the first row) */
174 : virtual nsresult GetRowIndex(int32_t &aRowIndex) const override;
175 :
176 : /**
177 : * return the cell's specified col span. this is what was specified in the
178 : * content model or in the style info, and is always >= 1.
179 : * to get the effective col span (the actual value that applies), use GetEffectiveColSpan()
180 : * @see nsTableFrame::GetEffectiveColSpan()
181 : */
182 : int32_t GetColSpan();
183 :
184 : /** return the cell's column index (starting at 0 for the first column) */
185 : virtual nsresult GetColIndex(int32_t &aColIndex) const override;
186 : void SetColIndex(int32_t aColIndex);
187 :
188 : /** return the available isize given to this frame during its last reflow */
189 : inline nscoord GetPriorAvailISize();
190 :
191 : /** set the available isize given to this frame during its last reflow */
192 : inline void SetPriorAvailISize(nscoord aPriorAvailISize);
193 :
194 : /** return the desired size returned by this frame during its last reflow */
195 : inline mozilla::LogicalSize GetDesiredSize();
196 :
197 : /** set the desired size returned by this frame during its last reflow */
198 : inline void SetDesiredSize(const ReflowOutput & aDesiredSize);
199 :
200 : bool GetContentEmpty();
201 : void SetContentEmpty(bool aContentEmpty);
202 :
203 : bool HasPctOverBSize();
204 : void SetHasPctOverBSize(bool aValue);
205 :
206 : nsTableCellFrame* GetNextCell() const;
207 :
208 : virtual LogicalMargin GetBorderWidth(WritingMode aWM) const;
209 :
210 : virtual DrawResult PaintBackground(gfxContext& aRenderingContext,
211 : const nsRect& aDirtyRect,
212 : nsPoint aPt,
213 : uint32_t aFlags);
214 :
215 : void DecorateForSelection(DrawTarget* aDrawTarget, nsPoint aPt);
216 :
217 : virtual bool ComputeCustomOverflow(nsOverflowAreas& aOverflowAreas) override;
218 :
219 0 : virtual bool IsFrameOfType(uint32_t aFlags) const override
220 : {
221 0 : return nsContainerFrame::IsFrameOfType(aFlags & ~(nsIFrame::eTablePart));
222 : }
223 :
224 : virtual void InvalidateFrame(uint32_t aDisplayItemKey = 0) override;
225 : virtual void InvalidateFrameWithRect(const nsRect& aRect, uint32_t aDisplayItemKey = 0) override;
226 0 : virtual void InvalidateFrameForRemoval() override { InvalidateFrameSubtree(); }
227 :
228 : protected:
229 : nsTableCellFrame(nsStyleContext* aContext, nsTableFrame* aTableFrame,
230 : ClassID aID);
231 : ~nsTableCellFrame();
232 :
233 : virtual LogicalSides
234 : GetLogicalSkipSides(const ReflowInput* aReflowInput = nullptr) const override;
235 :
236 : /**
237 : * GetBorderOverflow says how far the cell's own borders extend
238 : * outside its own bounds. In the separated borders model this should
239 : * just be zero (as it is for most frames), but in the collapsed
240 : * borders model (for which nsBCTableCellFrame overrides this virtual
241 : * method), it considers the extents of the collapsed border.
242 : */
243 : virtual nsMargin GetBorderOverflow();
244 :
245 : friend class nsTableRowFrame;
246 :
247 : uint32_t mColIndex; // the starting column for this cell
248 :
249 : nscoord mPriorAvailISize; // the avail isize during the last reflow
250 : mozilla::LogicalSize mDesiredSize; // the last desired inline and block size
251 : };
252 :
253 0 : inline nscoord nsTableCellFrame::GetPriorAvailISize()
254 0 : { return mPriorAvailISize; }
255 :
256 0 : inline void nsTableCellFrame::SetPriorAvailISize(nscoord aPriorAvailISize)
257 0 : { mPriorAvailISize = aPriorAvailISize; }
258 :
259 0 : inline mozilla::LogicalSize nsTableCellFrame::GetDesiredSize()
260 0 : { return mDesiredSize; }
261 :
262 0 : inline void nsTableCellFrame::SetDesiredSize(const ReflowOutput & aDesiredSize)
263 : {
264 0 : mozilla::WritingMode wm = aDesiredSize.GetWritingMode();
265 0 : mDesiredSize = aDesiredSize.Size(wm).ConvertTo(GetWritingMode(), wm);
266 0 : }
267 :
268 0 : inline bool nsTableCellFrame::GetContentEmpty()
269 : {
270 0 : return HasAnyStateBits(NS_TABLE_CELL_CONTENT_EMPTY);
271 : }
272 :
273 0 : inline void nsTableCellFrame::SetContentEmpty(bool aContentEmpty)
274 : {
275 0 : if (aContentEmpty) {
276 0 : AddStateBits(NS_TABLE_CELL_CONTENT_EMPTY);
277 : } else {
278 0 : RemoveStateBits(NS_TABLE_CELL_CONTENT_EMPTY);
279 : }
280 0 : }
281 :
282 : inline bool nsTableCellFrame::HasPctOverBSize()
283 : {
284 : return HasAnyStateBits(NS_TABLE_CELL_HAS_PCT_OVER_BSIZE);
285 : }
286 :
287 0 : inline void nsTableCellFrame::SetHasPctOverBSize(bool aValue)
288 : {
289 0 : if (aValue) {
290 0 : AddStateBits(NS_TABLE_CELL_HAS_PCT_OVER_BSIZE);
291 : } else {
292 0 : RemoveStateBits(NS_TABLE_CELL_HAS_PCT_OVER_BSIZE);
293 : }
294 0 : }
295 :
296 : // nsBCTableCellFrame
297 : class nsBCTableCellFrame final : public nsTableCellFrame
298 : {
299 : typedef mozilla::image::DrawResult DrawResult;
300 : public:
301 0 : NS_DECL_FRAMEARENA_HELPERS(nsBCTableCellFrame)
302 :
303 : nsBCTableCellFrame(nsStyleContext* aContext, nsTableFrame* aTableFrame);
304 :
305 : ~nsBCTableCellFrame();
306 :
307 : virtual nsMargin GetUsedBorder() const override;
308 : virtual bool GetBorderRadii(const nsSize& aFrameSize,
309 : const nsSize& aBorderArea,
310 : Sides aSkipSides,
311 : nscoord aRadii[8]) const override;
312 :
313 : // Get the *inner half of the border only*, in twips.
314 : virtual LogicalMargin GetBorderWidth(WritingMode aWM) const override;
315 :
316 : // Get the *inner half of the border only*, in pixels.
317 : BCPixelSize GetBorderWidth(LogicalSide aSide) const;
318 :
319 : // Set the full (both halves) width of the border
320 : void SetBorderWidth(LogicalSide aSide, BCPixelSize aPixelValue);
321 :
322 : virtual nsMargin GetBorderOverflow() override;
323 :
324 : #ifdef DEBUG_FRAME_DUMP
325 : virtual nsresult GetFrameName(nsAString& aResult) const override;
326 : #endif
327 :
328 : virtual DrawResult PaintBackground(gfxContext& aRenderingContext,
329 : const nsRect& aDirtyRect,
330 : nsPoint aPt,
331 : uint32_t aFlags) override;
332 :
333 : private:
334 :
335 : // These are the entire width of the border (the cell edge contains only
336 : // the inner half, per the macros in nsTablePainter.h).
337 : BCPixelSize mBStartBorder;
338 : BCPixelSize mIEndBorder;
339 : BCPixelSize mBEndBorder;
340 : BCPixelSize mIStartBorder;
341 : };
342 :
343 : #endif
|