Coverage Report

Created: 2018-09-25 14:53

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