Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/layout/tables/nsTableRowFrame.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 nsTableRowFrame_h__
6
#define nsTableRowFrame_h__
7
8
#include "mozilla/Attributes.h"
9
#include "nscore.h"
10
#include "nsContainerFrame.h"
11
#include "nsTableRowGroupFrame.h"
12
#include "mozilla/WritingModes.h"
13
14
class  nsTableCellFrame;
15
namespace mozilla {
16
struct TableCellReflowInput;
17
} // namespace mozilla
18
19
/**
20
 * nsTableRowFrame is the frame that maps table rows
21
 * (HTML tag TR). This class cannot be reused
22
 * outside of an nsTableRowGroupFrame.  It assumes that its parent is an nsTableRowGroupFrame,
23
 * and its children are nsTableCellFrames.
24
 *
25
 * @see nsTableFrame
26
 * @see nsTableRowGroupFrame
27
 * @see nsTableCellFrame
28
 */
29
class nsTableRowFrame : public nsContainerFrame
30
{
31
  using TableCellReflowInput = mozilla::TableCellReflowInput;
32
33
public:
34
  NS_DECL_QUERYFRAME
35
  NS_DECL_FRAMEARENA_HELPERS(nsTableRowFrame)
36
37
  virtual ~nsTableRowFrame();
38
39
  virtual void Init(nsIContent*       aContent,
40
                    nsContainerFrame* aParent,
41
                    nsIFrame*         aPrevInFlow) override;
42
43
  virtual void DestroyFrom(nsIFrame* aDestructRoot, PostDestroyData& aPostDestroyData) override;
44
45
  /** @see nsIFrame::DidSetComputedStyle */
46
  virtual void DidSetComputedStyle(ComputedStyle* aOldComputedStyle) override;
47
48
  virtual void AppendFrames(ChildListID     aListID,
49
                            nsFrameList&    aFrameList) override;
50
  virtual void InsertFrames(ChildListID     aListID,
51
                            nsIFrame*       aPrevFrame,
52
                            nsFrameList&    aFrameList) override;
53
  virtual void RemoveFrame(ChildListID     aListID,
54
                           nsIFrame*       aOldFrame) override;
55
56
  /** instantiate a new instance of nsTableRowFrame.
57
    * @param aPresShell the pres shell for this frame
58
    *
59
    * @return           the frame that was created
60
    */
61
  friend nsTableRowFrame* NS_NewTableRowFrame(nsIPresShell* aPresShell,
62
                                              ComputedStyle* aStyle);
63
64
  nsTableRowGroupFrame* GetTableRowGroupFrame() const
65
0
  {
66
0
    nsIFrame* parent = GetParent();
67
0
    MOZ_ASSERT(parent && parent->IsTableRowGroupFrame());
68
0
    return static_cast<nsTableRowGroupFrame*>(parent);
69
0
  }
70
71
  nsTableFrame* GetTableFrame() const
72
0
  {
73
0
    return GetTableRowGroupFrame()->GetTableFrame();
74
0
  }
75
76
  virtual nsMargin GetUsedMargin() const override;
77
  virtual nsMargin GetUsedBorder() const override;
78
  virtual nsMargin GetUsedPadding() const override;
79
80
  virtual void BuildDisplayList(nsDisplayListBuilder*   aBuilder,
81
                                const nsDisplayListSet& aLists) override;
82
83
  // Implemented in nsTableCellFrame.h, because it needs to know about the
84
  // nsTableCellFrame class, but we can't include nsTableCellFrame.h here.
85
  inline nsTableCellFrame* GetFirstCell() const;
86
87
  /** calls Reflow for all of its child cells.
88
    * Cells with rowspan=1 are all set to the same height and stacked horizontally.
89
    * <P> Cells are not split unless absolutely necessary.
90
    * <P> Cells are resized in nsTableFrame::BalanceColumnWidths
91
    * and nsTableFrame::ShrinkWrapChildren
92
    *
93
    * @param aDesiredSize width set to width of the sum of the cells, height set to
94
    *                     height of cells with rowspan=1.
95
    *
96
    * @see nsIFrame::Reflow
97
    * @see nsTableFrame::BalanceColumnWidths
98
    * @see nsTableFrame::ShrinkWrapChildren
99
    */
100
  virtual void Reflow(nsPresContext*           aPresContext,
101
                      ReflowOutput&     aDesiredSize,
102
                      const ReflowInput& aReflowInput,
103
                      nsReflowStatus&          aStatus) override;
104
105
  void DidResize();
106
107
#ifdef DEBUG_FRAME_DUMP
108
  virtual nsresult GetFrameName(nsAString& aResult) const override;
109
#endif
110
111
  void UpdateBSize(nscoord           aBSize,
112
                   nscoord           aAscent,
113
                   nscoord           aDescent,
114
                   nsTableFrame*     aTableFrame = nullptr,
115
                   nsTableCellFrame* aCellFrame  = nullptr);
116
117
  void ResetBSize(nscoord aRowStyleBSize);
118
119
  // calculate the bsize, considering content bsize of the
120
  // cells and the style bsize of the row and cells, excluding pct bsizes
121
  nscoord CalcBSize(const ReflowInput& aReflowInput);
122
123
  // Support for cells with 'vertical-align: baseline'.
124
125
  /**
126
   * returns the max-ascent amongst all the cells that have
127
   * 'vertical-align: baseline', *including* cells with rowspans.
128
   * returns 0 if we don't have any cell with 'vertical-align: baseline'
129
   */
130
  nscoord GetMaxCellAscent() const;
131
132
  /* return the row ascent
133
   */
134
  nscoord GetRowBaseline(mozilla::WritingMode aWritingMode);
135
136
  /** returns the ordinal position of this row in its table */
137
  virtual int32_t GetRowIndex() const;
138
139
  /** set this row's starting row index */
140
  void SetRowIndex (int aRowIndex);
141
142
  // See nsTableFrame.h
143
  int32_t GetAdjustmentForStoredIndex(int32_t aStoredIndex) const;
144
145
  // See nsTableFrame.h
146
  void AddDeletedRowIndex();
147
148
  /** used by row group frame code */
149
  nscoord ReflowCellFrame(nsPresContext*           aPresContext,
150
                          const ReflowInput& aReflowInput,
151
                          bool                     aIsTopOfPage,
152
                          nsTableCellFrame*        aCellFrame,
153
                          nscoord                  aAvailableBSize,
154
                          nsReflowStatus&          aStatus);
155
  /**
156
    * Collapse the row if required, apply col and colgroup visibility: collapse
157
    * info to the cells in the row.
158
    * @return the amount to shift bstart-wards all following rows
159
    * @param aRowOffset     - shift the row bstart-wards by this amount
160
    * @param aISize         - new isize of the row
161
    * @param aCollapseGroup - parent rowgroup is collapsed so this row needs
162
    *                         to be collapsed
163
    * @param aDidCollapse   - the row has been collapsed
164
    */
165
  nscoord CollapseRowIfNecessary(nscoord aRowOffset,
166
                                 nscoord aISize,
167
                                 bool    aCollapseGroup,
168
                                 bool&   aDidCollapse);
169
170
  /**
171
   * Insert a cell frame after the last cell frame that has a col index
172
   * that is less than aColIndex.  If no such cell frame is found the
173
   * frame to insert is prepended to the child list.
174
   * @param aFrame the cell frame to insert
175
   * @param aColIndex the col index
176
   */
177
  void InsertCellFrame(nsTableCellFrame* aFrame,
178
                       int32_t           aColIndex);
179
180
  nsresult CalculateCellActualBSize(nsTableCellFrame*    aCellFrame,
181
                                    nscoord&             aDesiredBSize,
182
                                    mozilla::WritingMode aWM);
183
184
  bool IsFirstInserted() const;
185
  void   SetFirstInserted(bool aValue);
186
187
  nscoord GetContentBSize() const;
188
  void    SetContentBSize(nscoord aTwipValue);
189
190
  bool HasStyleBSize() const;
191
192
  bool HasFixedBSize() const;
193
  void   SetHasFixedBSize(bool aValue);
194
195
  bool HasPctBSize() const;
196
  void   SetHasPctBSize(bool aValue);
197
198
  nscoord GetFixedBSize() const;
199
  void    SetFixedBSize(nscoord aValue);
200
201
  float   GetPctBSize() const;
202
  void    SetPctBSize(float  aPctValue,
203
                       bool aForce = false);
204
205
  nscoord GetInitialBSize(nscoord aBasis = 0) const;
206
207
  nsTableRowFrame* GetNextRow() const;
208
209
  bool    HasUnpaginatedBSize();
210
  void    SetHasUnpaginatedBSize(bool aValue);
211
  nscoord GetUnpaginatedBSize();
212
  void    SetUnpaginatedBSize(nsPresContext* aPresContext, nscoord aValue);
213
214
0
  BCPixelSize GetBStartBCBorderWidth() const { return mBStartBorderWidth; }
215
0
  BCPixelSize GetBEndBCBorderWidth() const { return mBEndBorderWidth; }
216
0
  void SetBStartBCBorderWidth(BCPixelSize aWidth) { mBStartBorderWidth = aWidth; }
217
0
  void SetBEndBCBorderWidth(BCPixelSize aWidth) { mBEndBorderWidth = aWidth; }
218
  mozilla::LogicalMargin GetBCBorderWidth(mozilla::WritingMode aWM);
219
220
  /**
221
   * Gets inner border widths before collapsing with cell borders
222
   * Caller must get block-end border from next row or from table
223
   * GetContinuousBCBorderWidth will not overwrite that border
224
   * see nsTablePainter about continuous borders
225
   */
226
  void GetContinuousBCBorderWidth(mozilla::WritingMode aWM,
227
                                  mozilla::LogicalMargin& aBorder);
228
229
  /**
230
   * @returns outer block-start bc border == prev row's block-end inner
231
   */
232
  nscoord GetOuterBStartContBCBorderWidth();
233
  /**
234
   * Sets full border widths before collapsing with cell borders
235
   * @param aForSide - side to set; only accepts iend, istart, and bstart
236
   */
237
  void SetContinuousBCBorderWidth(mozilla::LogicalSide aForSide,
238
                                  BCPixelSize aPixelValue);
239
240
  virtual bool IsFrameOfType(uint32_t aFlags) const override
241
0
  {
242
0
    if (aFlags & eSupportsContainLayoutAndPaint) {
243
0
      return false;
244
0
    }
245
0
246
0
    return nsContainerFrame::IsFrameOfType(aFlags & ~(nsIFrame::eTablePart));
247
0
  }
248
249
  virtual void InvalidateFrame(uint32_t aDisplayItemKey = 0, bool aRebuildDisplayItems = true) override;
250
  virtual void InvalidateFrameWithRect(const nsRect& aRect, uint32_t aDisplayItemKey = 0, bool aRebuildDisplayItems = true) override;
251
0
  virtual void InvalidateFrameForRemoval() override { InvalidateFrameSubtree(); }
252
253
#ifdef ACCESSIBILITY
254
  virtual mozilla::a11y::AccType AccessibleType() override;
255
#endif
256
257
protected:
258
259
  /** protected constructor.
260
    * @see NewFrame
261
    */
262
  explicit nsTableRowFrame(ComputedStyle* aStyle, ClassID aID = kClassID);
263
264
  void InitChildReflowInput(nsPresContext&              aPresContext,
265
                            const mozilla::LogicalSize& aAvailSize,
266
                            bool                        aBorderCollapse,
267
                            TableCellReflowInput&     aReflowInput);
268
269
  virtual LogicalSides GetLogicalSkipSides(const ReflowInput* aReflowInput = nullptr) const override;
270
271
  // row-specific methods
272
273
  nscoord ComputeCellXOffset(const ReflowInput& aState,
274
                             nsIFrame*                aKidFrame,
275
                             const nsMargin&          aKidMargin) const;
276
  /**
277
   * Called for incremental/dirty and resize reflows. If aDirtyOnly is true then
278
   * only reflow dirty cells.
279
   */
280
  void ReflowChildren(nsPresContext*           aPresContext,
281
                      ReflowOutput&     aDesiredSize,
282
                      const ReflowInput& aReflowInput,
283
                      nsTableFrame&            aTableFrame,
284
                      nsReflowStatus&          aStatus);
285
286
private:
287
  struct RowBits {
288
    unsigned mRowIndex:29;
289
    unsigned mHasFixedBSize:1; // set if the dominating style bsize on the row or any cell is pixel based
290
    unsigned mHasPctBSize:1;   // set if the dominating style bsize on the row or any cell is pct based
291
    unsigned mFirstInserted:1; // if true, then it was the bstart-most newly inserted row
292
  } mBits;
293
294
  // the desired bsize based on the content of the tallest cell in the row
295
  nscoord mContentBSize;
296
  // the bsize based on a style percentage bsize on either the row or any cell
297
  // if mHasPctBSize is set
298
  nscoord mStylePctBSize;
299
  // the bsize based on a style pixel bsize on the row or any
300
  // cell if mHasFixedBSize is set
301
  nscoord mStyleFixedBSize;
302
303
  // max-ascent and max-descent amongst all cells that have 'vertical-align: baseline'
304
  nscoord mMaxCellAscent;  // does include cells with rowspan > 1
305
  nscoord mMaxCellDescent; // does *not* include cells with rowspan > 1
306
307
  // border widths in pixels in the collapsing border model of the *inner*
308
  // half of the border only
309
  BCPixelSize mBStartBorderWidth;
310
  BCPixelSize mBEndBorderWidth;
311
  BCPixelSize mIEndContBorderWidth;
312
  BCPixelSize mBStartContBorderWidth;
313
  BCPixelSize mIStartContBorderWidth;
314
315
  /**
316
   * Sets the NS_ROW_HAS_CELL_WITH_STYLE_BSIZE bit to indicate whether
317
   * this row has any cells that have non-auto-bsize.  (Row-spanning
318
   * cells are ignored.)
319
   */
320
  void InitHasCellWithStyleBSize(nsTableFrame* aTableFrame);
321
322
};
323
324
inline int32_t
325
nsTableRowFrame::GetAdjustmentForStoredIndex(int32_t aStoredIndex) const
326
0
{
327
0
  nsTableRowGroupFrame* parentFrame = GetTableRowGroupFrame();
328
0
  return parentFrame->GetAdjustmentForStoredIndex(aStoredIndex);
329
0
}
330
331
inline void nsTableRowFrame::AddDeletedRowIndex()
332
0
{
333
0
  nsTableRowGroupFrame* parentFrame = GetTableRowGroupFrame();
334
0
  parentFrame->AddDeletedRowIndex(int32_t(mBits.mRowIndex));
335
0
}
336
337
inline int32_t nsTableRowFrame::GetRowIndex() const
338
0
{
339
0
  int32_t storedRowIndex = int32_t(mBits.mRowIndex);
340
0
  int32_t rowIndexAdjustment = GetAdjustmentForStoredIndex(storedRowIndex);
341
0
  return (storedRowIndex - rowIndexAdjustment);
342
0
}
343
344
inline void nsTableRowFrame::SetRowIndex (int aRowIndex)
345
0
{
346
0
  // Note: Setting the index of a row (as in the case of adding new rows) should
347
0
  // be preceded by a call to nsTableFrame::RecalculateRowIndices()
348
0
  // so as to correctly clear mDeletedRowIndexRanges.
349
0
  MOZ_ASSERT(GetTableRowGroupFrame()->
350
0
               GetTableFrame()->IsDeletedRowIndexRangesEmpty(),
351
0
             "mDeletedRowIndexRanges should be empty here!");
352
0
  mBits.mRowIndex = aRowIndex;
353
0
}
354
355
inline bool nsTableRowFrame::IsFirstInserted() const
356
0
{
357
0
  return bool(mBits.mFirstInserted);
358
0
}
359
360
inline void nsTableRowFrame::SetFirstInserted(bool aValue)
361
0
{
362
0
  mBits.mFirstInserted = aValue;
363
0
}
364
365
inline bool nsTableRowFrame::HasStyleBSize() const
366
0
{
367
0
  return (bool)mBits.mHasFixedBSize || (bool)mBits.mHasPctBSize;
368
0
}
369
370
inline bool nsTableRowFrame::HasFixedBSize() const
371
0
{
372
0
  return (bool)mBits.mHasFixedBSize;
373
0
}
374
375
inline void nsTableRowFrame::SetHasFixedBSize(bool aValue)
376
0
{
377
0
  mBits.mHasFixedBSize = aValue;
378
0
}
379
380
inline bool nsTableRowFrame::HasPctBSize() const
381
0
{
382
0
  return (bool)mBits.mHasPctBSize;
383
0
}
384
385
inline void nsTableRowFrame::SetHasPctBSize(bool aValue)
386
0
{
387
0
  mBits.mHasPctBSize = aValue;
388
0
}
389
390
inline nscoord nsTableRowFrame::GetContentBSize() const
391
0
{
392
0
  return mContentBSize;
393
0
}
394
395
inline void nsTableRowFrame::SetContentBSize(nscoord aValue)
396
0
{
397
0
  mContentBSize = aValue;
398
0
}
399
400
inline nscoord nsTableRowFrame::GetFixedBSize() const
401
0
{
402
0
  if (mBits.mHasFixedBSize) {
403
0
    return mStyleFixedBSize;
404
0
  }
405
0
  return 0;
406
0
}
407
408
inline float nsTableRowFrame::GetPctBSize() const
409
0
{
410
0
  if (mBits.mHasPctBSize) {
411
0
    return (float)mStylePctBSize / 100.0f;
412
0
  }
413
0
  return 0.0f;
414
0
}
415
416
inline bool nsTableRowFrame::HasUnpaginatedBSize()
417
0
{
418
0
  return HasAnyStateBits(NS_TABLE_ROW_HAS_UNPAGINATED_BSIZE);
419
0
}
420
421
inline void nsTableRowFrame::SetHasUnpaginatedBSize(bool aValue)
422
0
{
423
0
  if (aValue) {
424
0
    AddStateBits(NS_TABLE_ROW_HAS_UNPAGINATED_BSIZE);
425
0
  } else {
426
0
    RemoveStateBits(NS_TABLE_ROW_HAS_UNPAGINATED_BSIZE);
427
0
  }
428
0
}
429
430
inline mozilla::LogicalMargin
431
nsTableRowFrame::GetBCBorderWidth(mozilla::WritingMode aWM)
432
0
{
433
0
  nsPresContext* presContext = PresContext();
434
0
  return mozilla::LogicalMargin(
435
0
    aWM, presContext->DevPixelsToAppUnits(mBStartBorderWidth), 0,
436
0
    presContext->DevPixelsToAppUnits(mBEndBorderWidth), 0);
437
0
}
438
439
inline void
440
nsTableRowFrame::GetContinuousBCBorderWidth(mozilla::WritingMode aWM,
441
                                            mozilla::LogicalMargin& aBorder)
442
{
443
  int32_t d2a = PresContext()->AppUnitsPerDevPixel();
444
  aBorder.IEnd(aWM) = BC_BORDER_START_HALF_COORD(d2a,
445
                                                 mIStartContBorderWidth);
446
  aBorder.BStart(aWM) = BC_BORDER_END_HALF_COORD(d2a,
447
                                                 mBStartContBorderWidth);
448
  aBorder.IStart(aWM) = BC_BORDER_END_HALF_COORD(d2a,
449
                                                 mIEndContBorderWidth);
450
}
451
452
inline nscoord nsTableRowFrame::GetOuterBStartContBCBorderWidth()
453
{
454
  int32_t aPixelsToTwips = mozilla::AppUnitsPerCSSPixel();
455
  return BC_BORDER_START_HALF_COORD(aPixelsToTwips, mBStartContBorderWidth);
456
}
457
458
#endif