/work/obj-fuzz/dist/include/nsTableFrame.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 nsTableFrame_h__ |
6 | | #define nsTableFrame_h__ |
7 | | |
8 | | #include "mozilla/Attributes.h" |
9 | | #include "celldata.h" |
10 | | #include "imgIContainer.h" |
11 | | #include "nscore.h" |
12 | | #include "nsContainerFrame.h" |
13 | | #include "nsStyleCoord.h" |
14 | | #include "nsStyleConsts.h" |
15 | | #include "nsCellMap.h" |
16 | | #include "nsGkAtoms.h" |
17 | | #include "nsDisplayList.h" |
18 | | #include "TableArea.h" |
19 | | |
20 | | struct BCPaintBorderAction; |
21 | | class nsTableCellFrame; |
22 | | class nsTableCellMap; |
23 | | class nsTableColFrame; |
24 | | class nsTableRowGroupFrame; |
25 | | class nsTableRowFrame; |
26 | | class nsTableColGroupFrame; |
27 | | class nsITableLayoutStrategy; |
28 | | namespace mozilla { |
29 | | class WritingMode; |
30 | | class LogicalMargin; |
31 | | struct TableReflowInput; |
32 | | namespace layers { |
33 | | class StackingContextHelper; |
34 | | } |
35 | | } // namespace mozilla |
36 | | |
37 | | struct BCPropertyData; |
38 | | |
39 | | static inline bool |
40 | | IsTableCell(mozilla::LayoutFrameType frameType) |
41 | 0 | { |
42 | 0 | return frameType == mozilla::LayoutFrameType::TableCell || |
43 | 0 | frameType == mozilla::LayoutFrameType::BCTableCell; |
44 | 0 | } Unexecuted instantiation: Unified_cpp_dom_base4.cpp:IsTableCell(mozilla::LayoutFrameType) Unexecuted instantiation: Unified_cpp_accessible_generic0.cpp:IsTableCell(mozilla::LayoutFrameType) |
45 | | |
46 | | class nsDisplayTableItem : public nsDisplayItem |
47 | | { |
48 | | public: |
49 | | nsDisplayTableItem(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame, |
50 | | bool aDrawsBackground = true) : |
51 | | nsDisplayItem(aBuilder, aFrame), |
52 | | mPartHasFixedBackground(false), |
53 | | mDrawsBackground(aDrawsBackground) {} |
54 | | |
55 | | // With collapsed borders, parts of the collapsed border can extend outside |
56 | | // the table part frames, so allow this display element to blow out to our |
57 | | // overflow rect. This is also useful for row frames that have spanning |
58 | | // cells extending outside them. |
59 | | virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, |
60 | | bool* aSnap) const override; |
61 | | |
62 | | virtual nsDisplayItemGeometry* AllocateGeometry(nsDisplayListBuilder* aBuilder) override; |
63 | | virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder, |
64 | | const nsDisplayItemGeometry* aGeometry, |
65 | | nsRegion *aInvalidRegion) const override; |
66 | | |
67 | | void UpdateForFrameBackground(nsIFrame* aFrame); |
68 | | |
69 | | private: |
70 | | bool mPartHasFixedBackground; |
71 | | bool mDrawsBackground; |
72 | | }; |
73 | | |
74 | | class nsAutoPushCurrentTableItem |
75 | | { |
76 | | public: |
77 | | nsAutoPushCurrentTableItem() |
78 | | : mBuilder(nullptr) |
79 | | , mOldCurrentItem(nullptr) {} |
80 | | |
81 | | void Push(nsDisplayListBuilder* aBuilder, nsDisplayTableItem* aPushItem) |
82 | | { |
83 | | mBuilder = aBuilder; |
84 | | mOldCurrentItem = aBuilder->GetCurrentTableItem(); |
85 | | aBuilder->SetCurrentTableItem(aPushItem); |
86 | | #ifdef DEBUG |
87 | | mPushedItem = aPushItem; |
88 | | #endif |
89 | | } |
90 | | ~nsAutoPushCurrentTableItem() { |
91 | | if (!mBuilder) |
92 | | return; |
93 | | #ifdef DEBUG |
94 | | NS_ASSERTION(mBuilder->GetCurrentTableItem() == mPushedItem, |
95 | | "Someone messed with the current table item behind our back!"); |
96 | | #endif |
97 | | mBuilder->SetCurrentTableItem(mOldCurrentItem); |
98 | | } |
99 | | |
100 | | private: |
101 | | nsDisplayListBuilder* mBuilder; |
102 | | nsDisplayTableItem* mOldCurrentItem; |
103 | | #ifdef DEBUG |
104 | | nsDisplayTableItem* mPushedItem; |
105 | | #endif |
106 | | }; |
107 | | |
108 | | /* ============================================================================ */ |
109 | | |
110 | | enum nsTableColType { |
111 | | eColContent = 0, // there is real col content associated |
112 | | eColAnonymousCol = 1, // the result of a span on a col |
113 | | eColAnonymousColGroup = 2, // the result of a span on a col group |
114 | | eColAnonymousCell = 3 // the result of a cell alone |
115 | | }; |
116 | | |
117 | | /** |
118 | | * nsTableFrame maps the inner portion of a table (everything except captions.) |
119 | | * Used as a pseudo-frame within nsTableWrapperFrame, it may also be used |
120 | | * stand-alone as the top-level frame. |
121 | | * |
122 | | * The principal child list contains row group frames. There is also an |
123 | | * additional child list, kColGroupList, which contains the col group frames. |
124 | | */ |
125 | | class nsTableFrame : public nsContainerFrame |
126 | | { |
127 | | typedef mozilla::image::ImgDrawResult ImgDrawResult; |
128 | | typedef mozilla::WritingMode WritingMode; |
129 | | typedef mozilla::LogicalMargin LogicalMargin; |
130 | | typedef mozilla::TableReflowInput TableReflowInput; |
131 | | |
132 | | public: |
133 | | NS_DECL_FRAMEARENA_HELPERS(nsTableFrame) |
134 | | |
135 | | typedef nsTArray<nsIFrame*> FrameTArray; |
136 | | NS_DECLARE_FRAME_PROPERTY_DELETABLE(PositionedTablePartArray, FrameTArray) |
137 | | |
138 | | /** nsTableWrapperFrame has intimate knowledge of the inner table frame */ |
139 | | friend class nsTableWrapperFrame; |
140 | | |
141 | | /** instantiate a new instance of nsTableRowFrame. |
142 | | * @param aPresShell the pres shell for this frame |
143 | | * |
144 | | * @return the frame that was created |
145 | | */ |
146 | | friend nsTableFrame* NS_NewTableFrame(nsIPresShell* aPresShell, |
147 | | ComputedStyle* aStyle); |
148 | | |
149 | | /** sets defaults for table-specific style. |
150 | | * @see nsIFrame::Init |
151 | | */ |
152 | | virtual void Init(nsIContent* aContent, |
153 | | nsContainerFrame* aParent, |
154 | | nsIFrame* aPrevInFlow) override; |
155 | | |
156 | | static float GetTwipsToPixels(nsPresContext* aPresContext); |
157 | | |
158 | | // Return true if aParentReflowInput.frame or any of its ancestors within |
159 | | // the containing table have non-auto bsize. (e.g. pct or fixed bsize) |
160 | | static bool AncestorsHaveStyleBSize(const ReflowInput& aParentReflowInput); |
161 | | |
162 | | // See if a special bsize reflow will occur due to having a pct bsize when |
163 | | // the pct bsize basis may not yet be valid. |
164 | | static void CheckRequestSpecialBSizeReflow(const ReflowInput& aReflowInput); |
165 | | |
166 | | // Notify the frame and its ancestors (up to the containing table) that a special |
167 | | // height reflow will occur. |
168 | | static void RequestSpecialBSizeReflow(const ReflowInput& aReflowInput); |
169 | | |
170 | | static void RePositionViews(nsIFrame* aFrame); |
171 | | |
172 | | static bool PageBreakAfter(nsIFrame* aSourceFrame, |
173 | | nsIFrame* aNextFrame); |
174 | | |
175 | | // Register a positioned table part with its nsTableFrame. These objects will |
176 | | // be visited by FixupPositionedTableParts after reflow is complete. (See that |
177 | | // function for more explanation.) Should be called during frame construction. |
178 | | static void RegisterPositionedTablePart(nsIFrame* aFrame); |
179 | | |
180 | | // Unregister a positioned table part with its nsTableFrame. |
181 | | static void UnregisterPositionedTablePart(nsIFrame* aFrame, |
182 | | nsIFrame* aDestructRoot); |
183 | | |
184 | | nsPoint GetFirstSectionOrigin(const ReflowInput& aReflowInput) const; |
185 | | |
186 | | /* |
187 | | * Notification that rowspan or colspan has changed for content inside a |
188 | | * table cell |
189 | | */ |
190 | | void RowOrColSpanChanged(nsTableCellFrame* aCellFrame); |
191 | | |
192 | | /** @see nsIFrame::DestroyFrom */ |
193 | | virtual void DestroyFrom(nsIFrame* aDestructRoot, PostDestroyData& aPostDestroyData) override; |
194 | | |
195 | | /** @see nsIFrame::DidSetComputedStyle */ |
196 | | virtual void DidSetComputedStyle(ComputedStyle* aOldComputedStyle) override; |
197 | | |
198 | | virtual void SetInitialChildList(ChildListID aListID, |
199 | | nsFrameList& aChildList) override; |
200 | | virtual void AppendFrames(ChildListID aListID, |
201 | | nsFrameList& aFrameList) override; |
202 | | virtual void InsertFrames(ChildListID aListID, |
203 | | nsIFrame* aPrevFrame, |
204 | | nsFrameList& aFrameList) override; |
205 | | virtual void RemoveFrame(ChildListID aListID, |
206 | | nsIFrame* aOldFrame) override; |
207 | | |
208 | | virtual nsMargin GetUsedBorder() const override; |
209 | | virtual nsMargin GetUsedPadding() const override; |
210 | | virtual nsMargin GetUsedMargin() const override; |
211 | | |
212 | | // Get the offset from the border box to the area where the row groups fit |
213 | | LogicalMargin GetChildAreaOffset(const WritingMode aWM, |
214 | | const ReflowInput* aReflowInput) const; |
215 | | |
216 | | /** helper method to find the table parent of any table frame object */ |
217 | | static nsTableFrame* GetTableFrame(nsIFrame* aSourceFrame); |
218 | | |
219 | | /* Like GetTableFrame, but will set *aDidPassThrough to false if we don't |
220 | | * pass through aMustPassThrough on the way to the table. |
221 | | */ |
222 | | static nsTableFrame* GetTableFramePassingThrough(nsIFrame* aMustPassThrough, |
223 | | nsIFrame* aSourceFrame, |
224 | | bool* aDidPassThrough); |
225 | | |
226 | | typedef void (* DisplayGenericTablePartTraversal) |
227 | | (nsDisplayListBuilder* aBuilder, nsFrame* aFrame, |
228 | | const nsDisplayListSet& aLists); |
229 | | static void GenericTraversal(nsDisplayListBuilder* aBuilder, nsFrame* aFrame, |
230 | | const nsDisplayListSet& aLists); |
231 | | |
232 | | /** |
233 | | * Helper method to handle display common to table frames, rowgroup frames |
234 | | * and row frames. It creates a background display item for handling events |
235 | | * if necessary, an outline display item if necessary, and displays |
236 | | * all the the frame's children. |
237 | | * @param aDisplayItem the display item created for this part, or null |
238 | | * if this part's border/background painting is delegated to an ancestor |
239 | | * @param aTraversal a function that gets called to traverse the table |
240 | | * part's child frames and add their display list items to a |
241 | | * display list set. |
242 | | */ |
243 | | static void DisplayGenericTablePart(nsDisplayListBuilder* aBuilder, |
244 | | nsFrame* aFrame, |
245 | | const nsDisplayListSet& aLists, |
246 | | DisplayGenericTablePartTraversal aTraversal = GenericTraversal); |
247 | | |
248 | | // Return the closest sibling of aPriorChildFrame (including aPriroChildFrame) |
249 | | // of type aChildType. |
250 | | static nsIFrame* GetFrameAtOrBefore(nsIFrame* aParentFrame, |
251 | | nsIFrame* aPriorChildFrame, |
252 | | mozilla::LayoutFrameType aChildType); |
253 | | bool IsAutoBSize(mozilla::WritingMode aWM); |
254 | | |
255 | | /** @return true if aDisplayType represents a rowgroup of any sort |
256 | | * (header, footer, or body) |
257 | | */ |
258 | | bool IsRowGroup(mozilla::StyleDisplay aDisplayType) const; |
259 | | |
260 | | virtual const nsFrameList& GetChildList(ChildListID aListID) const override; |
261 | | virtual void GetChildLists(nsTArray<ChildList>* aLists) const override; |
262 | | |
263 | | virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, |
264 | | const nsDisplayListSet& aLists) override; |
265 | | |
266 | | /** Get the outer half (i.e., the part outside the height and width of |
267 | | * the table) of the largest segment (?) of border-collapsed border on |
268 | | * the table on each side, or 0 for non border-collapsed tables. |
269 | | */ |
270 | | LogicalMargin GetOuterBCBorder(const WritingMode aWM) const; |
271 | | |
272 | | /** Same as above, but only if it's included from the border-box width |
273 | | * of the table. |
274 | | */ |
275 | | LogicalMargin GetIncludedOuterBCBorder(const WritingMode aWM) const; |
276 | | |
277 | | /** Same as above, but only if it's excluded from the border-box width |
278 | | * of the table. This is the area that leaks out into the margin |
279 | | * (or potentially past it, if there is no margin). |
280 | | */ |
281 | | LogicalMargin GetExcludedOuterBCBorder(const WritingMode aWM) const; |
282 | | |
283 | | /** |
284 | | * In quirks mode, the size of the table background is reduced |
285 | | * by the outer BC border. Compute the reduction needed. |
286 | | */ |
287 | | nsMargin GetDeflationForBackground(nsPresContext* aPresContext) const; |
288 | | |
289 | | /** Get width of table + colgroup + col collapse: elements that |
290 | | * continue along the length of the whole iStart side. |
291 | | * see nsTablePainter about continuous borders |
292 | | */ |
293 | | nscoord GetContinuousIStartBCBorderWidth() const; |
294 | | void SetContinuousIStartBCBorderWidth(nscoord aValue); |
295 | | |
296 | | friend class nsDelayedCalcBCBorders; |
297 | | |
298 | | void AddBCDamageArea(const mozilla::TableArea& aValue); |
299 | | bool BCRecalcNeeded(ComputedStyle* aOldComputedStyle, |
300 | | ComputedStyle* aNewComputedStyle); |
301 | | void PaintBCBorders(DrawTarget& aDrawTarget, const nsRect& aDirtyRect); |
302 | | void CreateWebRenderCommandsForBCBorders(mozilla::wr::DisplayListBuilder& aBuilder, |
303 | | const mozilla::layers::StackingContextHelper& aSc, |
304 | | const nsRect& aVisibleRect, |
305 | | const nsPoint& aOffsetToReferenceFrame); |
306 | | |
307 | | virtual void MarkIntrinsicISizesDirty() override; |
308 | | // For border-collapse tables, the caller must not add padding and |
309 | | // border to the results of these functions. |
310 | | virtual nscoord GetMinISize(gfxContext *aRenderingContext) override; |
311 | | virtual nscoord GetPrefISize(gfxContext *aRenderingContext) override; |
312 | | IntrinsicISizeOffsetData IntrinsicISizeOffsets(nscoord aPercentageBasis = |
313 | | NS_UNCONSTRAINEDSIZE) override; |
314 | | |
315 | | virtual mozilla::LogicalSize |
316 | | ComputeSize(gfxContext* aRenderingContext, |
317 | | mozilla::WritingMode aWM, |
318 | | const mozilla::LogicalSize& aCBSize, |
319 | | nscoord aAvailableISize, |
320 | | const mozilla::LogicalSize& aMargin, |
321 | | const mozilla::LogicalSize& aBorder, |
322 | | const mozilla::LogicalSize& aPadding, |
323 | | ComputeSizeFlags aFlags) override; |
324 | | |
325 | | virtual mozilla::LogicalSize |
326 | | ComputeAutoSize(gfxContext* aRenderingContext, |
327 | | mozilla::WritingMode aWM, |
328 | | const mozilla::LogicalSize& aCBSize, |
329 | | nscoord aAvailableISize, |
330 | | const mozilla::LogicalSize& aMargin, |
331 | | const mozilla::LogicalSize& aBorder, |
332 | | const mozilla::LogicalSize& aPadding, |
333 | | ComputeSizeFlags aFlags) override; |
334 | | |
335 | | /** |
336 | | * A copy of nsFrame::ShrinkWidthToFit that calls a different |
337 | | * GetPrefISize, since tables have two different ones. |
338 | | */ |
339 | | nscoord TableShrinkISizeToFit(gfxContext *aRenderingContext, |
340 | | nscoord aWidthInCB); |
341 | | |
342 | | // XXXldb REWRITE THIS COMMENT! |
343 | | /** inner tables are reflowed in two steps. |
344 | | * <pre> |
345 | | * if mFirstPassValid is false, this is our first time through since content was last changed |
346 | | * set pass to 1 |
347 | | * do pass 1 |
348 | | * get min/max info for all cells in an infinite space |
349 | | * do column balancing |
350 | | * set mFirstPassValid to true |
351 | | * do pass 2 |
352 | | * use column widths to Reflow cells |
353 | | * </pre> |
354 | | * |
355 | | * @see nsIFrame::Reflow |
356 | | */ |
357 | | virtual void Reflow(nsPresContext* aPresContext, |
358 | | ReflowOutput& aDesiredSize, |
359 | | const ReflowInput& aReflowInput, |
360 | | nsReflowStatus& aStatus) override; |
361 | | |
362 | | void ReflowTable(ReflowOutput& aDesiredSize, |
363 | | const ReflowInput& aReflowInput, |
364 | | nscoord aAvailBSize, |
365 | | nsIFrame*& aLastChildReflowed, |
366 | | nsReflowStatus& aStatus); |
367 | | |
368 | | nsFrameList& GetColGroups(); |
369 | | |
370 | | virtual ComputedStyle* |
371 | | GetParentComputedStyle(nsIFrame** aProviderFrame) const override; |
372 | | |
373 | | virtual bool IsFrameOfType(uint32_t aFlags) const override |
374 | | { |
375 | | if (aFlags & eSupportsCSSTransforms) { |
376 | | return false; |
377 | | } |
378 | | return nsContainerFrame::IsFrameOfType(aFlags); |
379 | | } |
380 | | |
381 | | #ifdef DEBUG_FRAME_DUMP |
382 | | /** @see nsIFrame::GetFrameName */ |
383 | | virtual nsresult GetFrameName(nsAString& aResult) const override; |
384 | | #endif |
385 | | |
386 | | /** Return the isize of the column at aColIndex. |
387 | | * This may only be called on the table's first-in-flow. |
388 | | */ |
389 | | nscoord GetColumnISizeFromFirstInFlow(int32_t aColIndex); |
390 | | |
391 | | /** Helper to get the column spacing style value. |
392 | | * The argument refers to the space between column aColIndex and column |
393 | | * aColIndex + 1. An index of -1 indicates the padding between the table |
394 | | * and the left border, an index equal to the number of columns indicates |
395 | | * the padding between the table and the right border. |
396 | | * |
397 | | * Although in this class cell spacing does not depend on the index, it |
398 | | * may be important for overriding classes. |
399 | | */ |
400 | | virtual nscoord GetColSpacing(int32_t aColIndex); |
401 | | |
402 | | /** Helper to find the sum of the cell spacing between arbitrary columns. |
403 | | * The argument refers to the space between column aColIndex and column |
404 | | * aColIndex + 1. An index of -1 indicates the padding between the table |
405 | | * and the left border, an index equal to the number of columns indicates |
406 | | * the padding between the table and the right border. |
407 | | * |
408 | | * This method is equivalent to |
409 | | * nscoord result = 0; |
410 | | * for (i = aStartColIndex; i < aEndColIndex; i++) { |
411 | | * result += GetColSpacing(i); |
412 | | * } |
413 | | * return result; |
414 | | */ |
415 | | virtual nscoord GetColSpacing(int32_t aStartColIndex, |
416 | | int32_t aEndColIndex); |
417 | | |
418 | | /** Helper to get the row spacing style value. |
419 | | * The argument refers to the space between row aRowIndex and row |
420 | | * aRowIndex + 1. An index of -1 indicates the padding between the table |
421 | | * and the top border, an index equal to the number of rows indicates |
422 | | * the padding between the table and the bottom border. |
423 | | * |
424 | | * Although in this class cell spacing does not depend on the index, it |
425 | | * may be important for overriding classes. |
426 | | */ |
427 | | virtual nscoord GetRowSpacing(int32_t aRowIndex); |
428 | | |
429 | | /** Helper to find the sum of the cell spacing between arbitrary rows. |
430 | | * The argument refers to the space between row aRowIndex and row |
431 | | * aRowIndex + 1. An index of -1 indicates the padding between the table |
432 | | * and the top border, an index equal to the number of rows indicates |
433 | | * the padding between the table and the bottom border. |
434 | | * |
435 | | * This method is equivalent to |
436 | | * nscoord result = 0; |
437 | | * for (i = aStartRowIndex; i < aEndRowIndex; i++) { |
438 | | * result += GetRowSpacing(i); |
439 | | * } |
440 | | * return result; |
441 | | */ |
442 | | virtual nscoord GetRowSpacing(int32_t aStartRowIndex, |
443 | | int32_t aEndRowIndex); |
444 | | |
445 | | private: |
446 | | /* For the base implementation of nsTableFrame, cell spacing does not depend |
447 | | * on row/column indexing. |
448 | | */ |
449 | | nscoord GetColSpacing(); |
450 | | nscoord GetRowSpacing(); |
451 | | |
452 | | public: |
453 | | virtual nscoord GetLogicalBaseline(mozilla::WritingMode aWritingMode) const override; |
454 | | bool GetNaturalBaselineBOffset(mozilla::WritingMode aWM, |
455 | | BaselineSharingGroup aBaselineGroup, |
456 | | nscoord* aBaseline) const override; |
457 | | |
458 | | /** return the row span of a cell, taking into account row span magic at the bottom |
459 | | * of a table. The row span equals the number of rows spanned by aCell starting at |
460 | | * aStartRowIndex, and can be smaller if aStartRowIndex is greater than the row |
461 | | * index in which aCell originates. |
462 | | * |
463 | | * @param aStartRowIndex the cell |
464 | | * @param aCell the cell |
465 | | * |
466 | | * @return the row span, correcting for row spans that extend beyond the bottom |
467 | | * of the table. |
468 | | */ |
469 | | int32_t GetEffectiveRowSpan(int32_t aStartRowIndex, |
470 | | const nsTableCellFrame& aCell) const; |
471 | | int32_t GetEffectiveRowSpan(const nsTableCellFrame& aCell, |
472 | | nsCellMap* aCellMap = nullptr); |
473 | | |
474 | | /** return the col span of a cell, taking into account col span magic at the edge |
475 | | * of a table. |
476 | | * |
477 | | * @param aCell the cell |
478 | | * |
479 | | * @return the col span, correcting for col spans that extend beyond the edge |
480 | | * of the table. |
481 | | */ |
482 | | int32_t GetEffectiveColSpan(const nsTableCellFrame& aCell, |
483 | | nsCellMap* aCellMap = nullptr) const; |
484 | | |
485 | | /** indicate whether the row has more than one cell that either originates |
486 | | * or is spanned from the rows above |
487 | | */ |
488 | | bool HasMoreThanOneCell(int32_t aRowIndex) const; |
489 | | |
490 | | /** return the column frame associated with aColIndex |
491 | | * returns nullptr if the col frame has not yet been allocated, or if |
492 | | * aColIndex is out of range |
493 | | */ |
494 | | nsTableColFrame* GetColFrame(int32_t aColIndex) const; |
495 | | |
496 | | /** Insert a col frame reference into the colframe cache and adapt the cellmap |
497 | | * @param aColFrame - the column frame |
498 | | * @param aColIndex - index where the column should be inserted into the |
499 | | * colframe cache |
500 | | */ |
501 | | void InsertCol(nsTableColFrame& aColFrame, |
502 | | int32_t aColIndex); |
503 | | |
504 | | nsTableColGroupFrame* CreateSyntheticColGroupFrame(); |
505 | | |
506 | | int32_t DestroyAnonymousColFrames(int32_t aNumFrames); |
507 | | |
508 | | // Append aNumColsToAdd anonymous col frames of type eColAnonymousCell to our |
509 | | // last synthetic colgroup. If we have no such colgroup, then create one. |
510 | | void AppendAnonymousColFrames(int32_t aNumColsToAdd); |
511 | | |
512 | | // Append aNumColsToAdd anonymous col frames of type aColType to |
513 | | // aColGroupFrame. If aAddToTable is true, also call AddColsToTable on the |
514 | | // new cols. |
515 | | void AppendAnonymousColFrames(nsTableColGroupFrame* aColGroupFrame, |
516 | | int32_t aNumColsToAdd, |
517 | | nsTableColType aColType, |
518 | | bool aAddToTable); |
519 | | |
520 | | void MatchCellMapToColCache(nsTableCellMap* aCellMap); |
521 | | /** empty the column frame cache */ |
522 | | void ClearColCache(); |
523 | | |
524 | | void DidResizeColumns(); |
525 | | |
526 | | void AppendCell(nsTableCellFrame& aCellFrame, |
527 | | int32_t aRowIndex); |
528 | | |
529 | | void InsertCells(nsTArray<nsTableCellFrame*>& aCellFrames, |
530 | | int32_t aRowIndex, |
531 | | int32_t aColIndexBefore); |
532 | | |
533 | | void RemoveCell(nsTableCellFrame* aCellFrame, |
534 | | int32_t aRowIndex); |
535 | | |
536 | | void AppendRows(nsTableRowGroupFrame* aRowGroupFrame, |
537 | | int32_t aRowIndex, |
538 | | nsTArray<nsTableRowFrame*>& aRowFrames); |
539 | | |
540 | | int32_t InsertRows(nsTableRowGroupFrame* aRowGroupFrame, |
541 | | nsTArray<nsTableRowFrame*>& aFrames, |
542 | | int32_t aRowIndex, |
543 | | bool aConsiderSpans); |
544 | | |
545 | | void RemoveRows(nsTableRowFrame& aFirstRowFrame, |
546 | | int32_t aNumRowsToRemove, |
547 | | bool aConsiderSpans); |
548 | | |
549 | | /** Insert multiple rowgroups into the table cellmap handling |
550 | | * @param aRowGroups - iterator that iterates over the rowgroups to insert |
551 | | */ |
552 | | void InsertRowGroups(const nsFrameList::Slice& aRowGroups); |
553 | | |
554 | | void InsertColGroups(int32_t aStartColIndex, |
555 | | const nsFrameList::Slice& aColgroups); |
556 | | |
557 | | void RemoveCol(nsTableColGroupFrame* aColGroupFrame, |
558 | | int32_t aColIndex, |
559 | | bool aRemoveFromCache, |
560 | | bool aRemoveFromCellMap); |
561 | | |
562 | | bool ColumnHasCellSpacingBefore(int32_t aColIndex) const; |
563 | | |
564 | | bool HasPctCol() const; |
565 | | void SetHasPctCol(bool aValue); |
566 | | |
567 | | bool HasCellSpanningPctCol() const; |
568 | | void SetHasCellSpanningPctCol(bool aValue); |
569 | | |
570 | | /** |
571 | | * To be called on a frame by its parent after setting its size/position and |
572 | | * calling DidReflow (possibly via FinishReflowChild()). This can also be |
573 | | * used for child frames which are not being reflowed but did have their size |
574 | | * or position changed. |
575 | | * |
576 | | * @param aFrame The frame to invalidate |
577 | | * @param aOrigRect The original rect of aFrame (before the change). |
578 | | * @param aOrigVisualOverflow The original overflow rect of aFrame. |
579 | | * @param aIsFirstReflow True if the size/position change is due to the |
580 | | * first reflow of aFrame. |
581 | | */ |
582 | | static void InvalidateTableFrame(nsIFrame* aFrame, |
583 | | const nsRect& aOrigRect, |
584 | | const nsRect& aOrigVisualOverflow, |
585 | | bool aIsFirstReflow); |
586 | | |
587 | | virtual bool ComputeCustomOverflow(nsOverflowAreas& aOverflowAreas) override; |
588 | | |
589 | | // Return our wrapper frame. |
590 | | void AppendDirectlyOwnedAnonBoxes(nsTArray<OwnedAnonBox>& aResult) override; |
591 | | |
592 | | protected: |
593 | | static void UpdateStyleOfOwnedAnonBoxesForTableWrapper( |
594 | | nsIFrame* aOwningFrame, |
595 | | nsIFrame* aWrapperFrame, |
596 | | mozilla::ServoRestyleState& aRestyleState); |
597 | | |
598 | | /** protected constructor. |
599 | | * @see NewFrame |
600 | | */ |
601 | | explicit nsTableFrame(ComputedStyle* aStyle, ClassID aID = kClassID); |
602 | | |
603 | | /** destructor, responsible for mColumnLayoutData */ |
604 | | virtual ~nsTableFrame(); |
605 | | |
606 | | void InitChildReflowInput(ReflowInput& aReflowInput); |
607 | | |
608 | | virtual LogicalSides GetLogicalSkipSides(const ReflowInput* aReflowInput = nullptr) const override; |
609 | | |
610 | | void IterateBCBorders(BCPaintBorderAction& aAction, const nsRect& aDirtyRect); |
611 | | |
612 | | public: |
613 | | bool IsRowInserted() const; |
614 | | void SetRowInserted(bool aValue); |
615 | | |
616 | | protected: |
617 | | |
618 | | // A helper function to reflow a header or footer with unconstrained height |
619 | | // to see if it should be made repeatable and also to determine its desired |
620 | | // height. |
621 | | nsresult SetupHeaderFooterChild(const TableReflowInput& aReflowInput, |
622 | | nsTableRowGroupFrame* aFrame, |
623 | | nscoord* aDesiredHeight); |
624 | | |
625 | | void ReflowChildren(TableReflowInput& aReflowInput, |
626 | | nsReflowStatus& aStatus, |
627 | | nsIFrame*& aLastChildReflowed, |
628 | | nsOverflowAreas& aOverflowAreas); |
629 | | |
630 | | // This calls the col group and column reflow methods, which do two things: |
631 | | // (1) set all the dimensions to 0 |
632 | | // (2) notify the table about colgroups or columns with hidden visibility |
633 | | void ReflowColGroups(gfxContext* aRenderingContext); |
634 | | |
635 | | /** return the isize of the table taking into account visibility collapse |
636 | | * on columns and colgroups |
637 | | * @param aBorderPadding the border and padding of the table |
638 | | */ |
639 | | nscoord GetCollapsedISize(const WritingMode aWM, |
640 | | const LogicalMargin& aBorderPadding); |
641 | | |
642 | | |
643 | | /** Adjust the table for visibility.collapse set on rowgroups, rows, |
644 | | * colgroups and cols |
645 | | * @param aDesiredSize the metrics of the table |
646 | | * @param aBorderPadding the border and padding of the table |
647 | | */ |
648 | | void AdjustForCollapsingRowsCols(ReflowOutput& aDesiredSize, |
649 | | const WritingMode aWM, |
650 | | const LogicalMargin& aBorderPadding); |
651 | | |
652 | | /** FixupPositionedTableParts is called at the end of table reflow to reflow |
653 | | * the absolutely positioned descendants of positioned table parts. This is |
654 | | * necessary because the dimensions of table parts may change after they've |
655 | | * been reflowed (e.g. in AdjustForCollapsingRowsCols). |
656 | | */ |
657 | | void FixupPositionedTableParts(nsPresContext* aPresContext, |
658 | | ReflowOutput& aDesiredSize, |
659 | | const ReflowInput& aReflowInput); |
660 | | |
661 | | // Clears the list of positioned table parts. |
662 | | void ClearAllPositionedTableParts(); |
663 | | |
664 | | nsITableLayoutStrategy* LayoutStrategy() const { |
665 | | return static_cast<nsTableFrame*>(FirstInFlow())-> |
666 | | mTableLayoutStrategy; |
667 | | } |
668 | | |
669 | | // Helper for InsertFrames. |
670 | | void HomogenousInsertFrames(ChildListID aListID, |
671 | | nsIFrame* aPrevFrame, |
672 | | nsFrameList& aFrameList); |
673 | | private: |
674 | | /* Handle a row that got inserted during reflow. aNewHeight is the |
675 | | new height of the table after reflow. */ |
676 | | void ProcessRowInserted(nscoord aNewHeight); |
677 | | |
678 | | // WIDTH AND HEIGHT CALCULATION |
679 | | |
680 | | public: |
681 | | |
682 | | // calculate the computed block-size of aFrame including its border and |
683 | | // padding given its reflow state. |
684 | | nscoord CalcBorderBoxBSize(const ReflowInput& aReflowInput); |
685 | | |
686 | | protected: |
687 | | |
688 | | // update the desired block-size of this table taking into account the current |
689 | | // reflow state, the table attributes and the content driven rowgroup bsizes |
690 | | // this function can change the overflow area |
691 | | void CalcDesiredBSize(const ReflowInput& aReflowInput, |
692 | | ReflowOutput& aDesiredSize); |
693 | | |
694 | | // The following is a helper for CalcDesiredBSize |
695 | | |
696 | | void DistributeBSizeToRows(const ReflowInput& aReflowInput, |
697 | | nscoord aAmount); |
698 | | |
699 | | void PlaceChild(TableReflowInput& aReflowInput, |
700 | | nsIFrame* aKidFrame, |
701 | | nsPoint aKidPosition, |
702 | | ReflowOutput& aKidDesiredSize, |
703 | | const nsRect& aOriginalKidRect, |
704 | | const nsRect& aOriginalKidVisualOverflow); |
705 | | void PlaceRepeatedFooter(TableReflowInput& aReflowInput, |
706 | | nsTableRowGroupFrame *aTfoot, |
707 | | nscoord aFooterHeight); |
708 | | |
709 | | nsIFrame* GetFirstBodyRowGroupFrame(); |
710 | | public: |
711 | | typedef AutoTArray<nsTableRowGroupFrame*, 8> RowGroupArray; |
712 | | /** |
713 | | * Push all our child frames from the aRowGroups array, in order, starting |
714 | | * from the frame at aPushFrom to the end of the array. The frames are put on |
715 | | * our overflow list or moved directly to our next-in-flow if one exists. |
716 | | */ |
717 | | protected: |
718 | | void PushChildren(const RowGroupArray& aRowGroups, int32_t aPushFrom); |
719 | | |
720 | | public: |
721 | | // put the children frames in the display order (e.g. thead before tbodies |
722 | | // before tfoot). This will handle calling GetRowGroupFrame() on the |
723 | | // children, and not append nulls, so the array is guaranteed to contain |
724 | | // nsTableRowGroupFrames. If there are multiple theads or tfoots, all but |
725 | | // the first one are treated as tbodies instead. |
726 | | |
727 | | void OrderRowGroups(RowGroupArray& aChildren, |
728 | | nsTableRowGroupFrame** aHead = nullptr, |
729 | | nsTableRowGroupFrame** aFoot = nullptr) const; |
730 | | |
731 | | // Return the thead, if any |
732 | | nsTableRowGroupFrame* GetTHead() const; |
733 | | |
734 | | // Return the tfoot, if any |
735 | | nsTableRowGroupFrame* GetTFoot() const; |
736 | | |
737 | | // Returns true if there are any cells above the row at |
738 | | // aRowIndex and spanning into the row at aRowIndex, the number of |
739 | | // effective columns limits the search up to that column |
740 | | bool RowIsSpannedInto(int32_t aRowIndex, int32_t aNumEffCols); |
741 | | |
742 | | // Returns true if there is a cell originating in aRowIndex |
743 | | // which spans into the next row, the number of effective |
744 | | // columns limits the search up to that column |
745 | | bool RowHasSpanningCells(int32_t aRowIndex, int32_t aNumEffCols); |
746 | | |
747 | | protected: |
748 | | |
749 | | bool HaveReflowedColGroups() const; |
750 | | void SetHaveReflowedColGroups(bool aValue); |
751 | | |
752 | | public: |
753 | | bool IsBorderCollapse() const; |
754 | | |
755 | | bool NeedToCalcBCBorders() const; |
756 | | void SetNeedToCalcBCBorders(bool aValue); |
757 | | |
758 | | bool NeedToCollapse() const; |
759 | | void SetNeedToCollapse(bool aValue); |
760 | | |
761 | | bool NeedToCalcHasBCBorders() const; |
762 | | void SetNeedToCalcHasBCBorders(bool aValue); |
763 | | |
764 | | void CalcHasBCBorders(); |
765 | | bool HasBCBorders(); |
766 | | void SetHasBCBorders(bool aValue); |
767 | | |
768 | | /** The GeometryDirty bit is similar to the NS_FRAME_IS_DIRTY frame |
769 | | * state bit, which implies that all descendants are dirty. The |
770 | | * GeometryDirty still implies that all the parts of the table are |
771 | | * dirty, but resizing optimizations should still apply to the |
772 | | * contents of the individual cells. |
773 | | */ |
774 | | void SetGeometryDirty() { mBits.mGeometryDirty = true; } |
775 | | void ClearGeometryDirty() { mBits.mGeometryDirty = false; } |
776 | | bool IsGeometryDirty() const { return mBits.mGeometryDirty; } |
777 | | |
778 | | /** Get the cell map for this table frame. It is not always mCellMap. |
779 | | * Only the firstInFlow has a legit cell map |
780 | | */ |
781 | | nsTableCellMap* GetCellMap() const; |
782 | | |
783 | | /** Iterate over the row groups and adjust the row indices of all rows |
784 | | * whose index is >= aRowIndex. |
785 | | * @param aRowIndex - start adjusting with this index |
786 | | * @param aAdjustment - shift the row index by this amount |
787 | | */ |
788 | | void AdjustRowIndices(int32_t aRowIndex, |
789 | | int32_t aAdjustment); |
790 | | |
791 | | /** Reset the rowindices of all rows as they might have changed due to |
792 | | * rowgroup reordering, exclude new row group frames that show in the |
793 | | * reordering but are not yet inserted into the cellmap |
794 | | * @param aRowGroupsToExclude - an iterator that will produce the row groups |
795 | | * to exclude. |
796 | | */ |
797 | | void ResetRowIndices(const nsFrameList::Slice& aRowGroupsToExclude); |
798 | | |
799 | | nsTArray<nsTableColFrame*>& GetColCache(); |
800 | | |
801 | | |
802 | | protected: |
803 | | |
804 | | void SetBorderCollapse(bool aValue); |
805 | | |
806 | | BCPropertyData* GetBCProperty() const; |
807 | | BCPropertyData* GetOrCreateBCProperty(); |
808 | | void SetFullBCDamageArea(); |
809 | | void CalcBCBorders(); |
810 | | |
811 | | void ExpandBCDamageArea(mozilla::TableArea& aRect) const; |
812 | | |
813 | | void SetColumnDimensions(nscoord aHeight, WritingMode aWM, |
814 | | const LogicalMargin& aBorderPadding, |
815 | | const nsSize& aContainerSize); |
816 | | |
817 | | int32_t CollectRows(nsIFrame* aFrame, |
818 | | nsTArray<nsTableRowFrame*>& aCollection); |
819 | | |
820 | | public: /* ----- Cell Map public methods ----- */ |
821 | | |
822 | | int32_t GetStartRowIndex(nsTableRowGroupFrame* aRowGroupFrame); |
823 | | |
824 | | /** returns the number of rows in this table. |
825 | | */ |
826 | | int32_t GetRowCount () const |
827 | | { |
828 | | return GetCellMap()->GetRowCount(); |
829 | | } |
830 | | |
831 | | /** returns the number of columns in this table after redundant columns have been removed |
832 | | */ |
833 | | int32_t GetEffectiveColCount() const; |
834 | | |
835 | | /* return the col count including dead cols */ |
836 | | int32_t GetColCount () const |
837 | | { |
838 | | return GetCellMap()->GetColCount(); |
839 | | } |
840 | | |
841 | | // return the last col index which isn't of type eColAnonymousCell |
842 | | int32_t GetIndexOfLastRealCol(); |
843 | | |
844 | | /** returns true if table-layout:auto */ |
845 | | bool IsAutoLayout(); |
846 | | |
847 | | public: |
848 | | |
849 | | /* ---------- Row index management methods ------------ */ |
850 | | |
851 | | /** Add the given index to the existing ranges of |
852 | | * deleted row indices and merge ranges if, with the addition of the new |
853 | | * index, they become consecutive. |
854 | | * @param aDeletedRowStoredIndex - index of the row that was deleted |
855 | | * Note - 'stored' index here refers to the index that was assigned to |
856 | | * the row before any remove row operations were performed i.e. the |
857 | | * value of mRowIndex and not the value returned by GetRowIndex() |
858 | | */ |
859 | | void AddDeletedRowIndex(int32_t aDeletedRowStoredIndex); |
860 | | |
861 | | /** Calculate the change that aStoredIndex must be increased/decreased by |
862 | | * to get new index. |
863 | | * Note that aStoredIndex is always the index of an undeleted row (since |
864 | | * rows that have already been deleted can never call this method). |
865 | | * @param aStoredIndex - The stored index value that must be adjusted |
866 | | * Note - 'stored' index here refers to the index that was assigned to |
867 | | * the row before any remove row operations were performed i.e. the |
868 | | * value of mRowIndex and not the value returned by GetRowIndex() |
869 | | */ |
870 | | int32_t GetAdjustmentForStoredIndex(int32_t aStoredIndex); |
871 | | |
872 | | /** Returns whether mDeletedRowIndexRanges is empty |
873 | | */ |
874 | | bool IsDeletedRowIndexRangesEmpty() const { |
875 | | return mDeletedRowIndexRanges.empty(); |
876 | | } |
877 | | |
878 | | public: |
879 | | |
880 | | #ifdef DEBUG |
881 | | void Dump(bool aDumpRows, |
882 | | bool aDumpCols, |
883 | | bool aDumpCellMap); |
884 | | #endif |
885 | | |
886 | | protected: |
887 | | /** |
888 | | * Helper method for RemoveFrame. |
889 | | */ |
890 | | void DoRemoveFrame(ChildListID aListID, nsIFrame* aOldFrame); |
891 | | #ifdef DEBUG |
892 | | void DumpRowGroup(nsIFrame* aChildFrame); |
893 | | #endif |
894 | | // DATA MEMBERS |
895 | | AutoTArray<nsTableColFrame*, 8> mColFrames; |
896 | | |
897 | | struct TableBits { |
898 | | uint32_t mHaveReflowedColGroups:1; // have the col groups gotten their initial reflow |
899 | | uint32_t mHasPctCol:1; // does any cell or col have a pct width |
900 | | uint32_t mCellSpansPctCol:1; // does any cell span a col with a pct width (or containing a cell with a pct width) |
901 | | uint32_t mIsBorderCollapse:1; // border collapsing model vs. separate model |
902 | | uint32_t mRowInserted:1; |
903 | | uint32_t mNeedToCalcBCBorders:1; |
904 | | uint32_t mGeometryDirty:1; |
905 | | uint32_t mIStartContBCBorder:8; |
906 | | uint32_t mNeedToCollapse:1; // rows, cols that have visibility:collapse need to be collapsed |
907 | | uint32_t mResizedColumns:1; // have we resized columns since last reflow? |
908 | | uint32_t mNeedToCalcHasBCBorders:1; |
909 | | uint32_t mHasBCBorders:1; |
910 | | } mBits; |
911 | | |
912 | | std::map<int32_t, int32_t> mDeletedRowIndexRanges; // maintains ranges of row |
913 | | // indices of deleted rows |
914 | | nsTableCellMap* mCellMap; // maintains the relationships between rows, cols, and cells |
915 | | nsITableLayoutStrategy* mTableLayoutStrategy;// the layout strategy for this frame |
916 | | nsFrameList mColGroups; // the list of colgroup frames |
917 | | }; |
918 | | |
919 | | |
920 | | inline bool nsTableFrame::IsRowGroup(mozilla::StyleDisplay aDisplayType) const |
921 | | { |
922 | | return mozilla::StyleDisplay::TableHeaderGroup == aDisplayType || |
923 | | mozilla::StyleDisplay::TableFooterGroup == aDisplayType || |
924 | | mozilla::StyleDisplay::TableRowGroup == aDisplayType; |
925 | | } |
926 | | |
927 | | inline void nsTableFrame::SetHaveReflowedColGroups(bool aValue) |
928 | | { |
929 | | mBits.mHaveReflowedColGroups = aValue; |
930 | | } |
931 | | |
932 | | inline bool nsTableFrame::HaveReflowedColGroups() const |
933 | | { |
934 | | return (bool)mBits.mHaveReflowedColGroups; |
935 | | } |
936 | | |
937 | | inline bool nsTableFrame::HasPctCol() const |
938 | 0 | { |
939 | 0 | return (bool)mBits.mHasPctCol; |
940 | 0 | } |
941 | | |
942 | | inline void nsTableFrame::SetHasPctCol(bool aValue) |
943 | 0 | { |
944 | 0 | mBits.mHasPctCol = (unsigned)aValue; |
945 | 0 | } |
946 | | |
947 | | inline bool nsTableFrame::HasCellSpanningPctCol() const |
948 | 0 | { |
949 | 0 | return (bool)mBits.mCellSpansPctCol; |
950 | 0 | } |
951 | | |
952 | | inline void nsTableFrame::SetHasCellSpanningPctCol(bool aValue) |
953 | 0 | { |
954 | 0 | mBits.mCellSpansPctCol = (unsigned)aValue; |
955 | 0 | } |
956 | | |
957 | | inline bool nsTableFrame::IsRowInserted() const |
958 | | { |
959 | | return (bool)mBits.mRowInserted; |
960 | | } |
961 | | |
962 | | inline void nsTableFrame::SetRowInserted(bool aValue) |
963 | | { |
964 | | mBits.mRowInserted = (unsigned)aValue; |
965 | | } |
966 | | |
967 | | inline void nsTableFrame::SetNeedToCollapse(bool aValue) |
968 | | { |
969 | | static_cast<nsTableFrame*>(FirstInFlow())->mBits.mNeedToCollapse = (unsigned)aValue; |
970 | | } |
971 | | |
972 | | inline bool nsTableFrame::NeedToCollapse() const |
973 | | { |
974 | | return (bool) static_cast<nsTableFrame*>(FirstInFlow())->mBits.mNeedToCollapse; |
975 | | } |
976 | | |
977 | | inline nsFrameList& nsTableFrame::GetColGroups() |
978 | | { |
979 | | return static_cast<nsTableFrame*>(FirstInFlow())->mColGroups; |
980 | | } |
981 | | |
982 | | inline nsTArray<nsTableColFrame*>& nsTableFrame::GetColCache() |
983 | 0 | { |
984 | 0 | return mColFrames; |
985 | 0 | } |
986 | | |
987 | | inline bool nsTableFrame::IsBorderCollapse() const |
988 | | { |
989 | | return (bool)mBits.mIsBorderCollapse; |
990 | | } |
991 | | |
992 | | inline void nsTableFrame::SetBorderCollapse(bool aValue) |
993 | | { |
994 | | mBits.mIsBorderCollapse = aValue; |
995 | | } |
996 | | |
997 | | inline bool nsTableFrame::NeedToCalcBCBorders() const |
998 | | { |
999 | | return (bool)mBits.mNeedToCalcBCBorders; |
1000 | | } |
1001 | | |
1002 | | inline void nsTableFrame::SetNeedToCalcBCBorders(bool aValue) |
1003 | | { |
1004 | | mBits.mNeedToCalcBCBorders = (unsigned)aValue; |
1005 | | } |
1006 | | |
1007 | | inline bool nsTableFrame::NeedToCalcHasBCBorders() const |
1008 | | { |
1009 | | return (bool)mBits.mNeedToCalcHasBCBorders; |
1010 | | } |
1011 | | |
1012 | | inline void nsTableFrame::SetNeedToCalcHasBCBorders(bool aValue) |
1013 | | { |
1014 | | mBits.mNeedToCalcHasBCBorders = (unsigned)aValue; |
1015 | | } |
1016 | | |
1017 | | inline bool nsTableFrame::HasBCBorders() |
1018 | | { |
1019 | | if (NeedToCalcHasBCBorders()) { |
1020 | | CalcHasBCBorders(); |
1021 | | SetNeedToCalcHasBCBorders(false); |
1022 | | } |
1023 | | return (bool)mBits.mHasBCBorders; |
1024 | | } |
1025 | | |
1026 | | inline void nsTableFrame::SetHasBCBorders(bool aValue) |
1027 | | { |
1028 | | mBits.mHasBCBorders = (unsigned)aValue; |
1029 | | } |
1030 | | |
1031 | | inline nscoord |
1032 | | nsTableFrame::GetContinuousIStartBCBorderWidth() const |
1033 | 0 | { |
1034 | 0 | int32_t d2a = PresContext()->AppUnitsPerDevPixel(); |
1035 | 0 | return BC_BORDER_END_HALF_COORD(d2a, mBits.mIStartContBCBorder); |
1036 | 0 | } |
1037 | | |
1038 | | inline void nsTableFrame::SetContinuousIStartBCBorderWidth(nscoord aValue) |
1039 | | { |
1040 | | mBits.mIStartContBCBorder = (unsigned) aValue; |
1041 | | } |
1042 | | |
1043 | | #define ABORT0() \ |
1044 | | {NS_ASSERTION(false, "CellIterator program error"); \ |
1045 | | return;} |
1046 | | |
1047 | | #define ABORT1(aReturn) \ |
1048 | | {NS_ASSERTION(false, "CellIterator program error"); \ |
1049 | | return aReturn;} |
1050 | | |
1051 | | #endif |