Bug 417561, disable tagging of Talkback now we have prebuilt packages, r=rhelmer
[mozilla-1.9.git] / layout / tables / nsTableRowGroupFrame.h
blob33463ee0545b92f4cf904dd1a803af628ddd629c
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* ***** BEGIN LICENSE BLOCK *****
3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 * The contents of this file are subject to the Mozilla Public License Version
6 * 1.1 (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 * http://www.mozilla.org/MPL/
10 * Software distributed under the License is distributed on an "AS IS" basis,
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 * for the specific language governing rights and limitations under the
13 * License.
15 * The Original Code is mozilla.org code.
17 * The Initial Developer of the Original Code is
18 * Netscape Communications Corporation.
19 * Portions created by the Initial Developer are Copyright (C) 1998
20 * the Initial Developer. All Rights Reserved.
22 * Contributor(s):
24 * Alternatively, the contents of this file may be used under the terms of
25 * either of the GNU General Public License Version 2 or later (the "GPL"),
26 * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 * in which case the provisions of the GPL or the LGPL are applicable instead
28 * of those above. If you wish to allow use of your version of this file only
29 * under the terms of either the GPL or the LGPL, and not to allow others to
30 * use your version of this file under the terms of the MPL, indicate your
31 * decision by deleting the provisions above and replace them with the notice
32 * and other provisions required by the GPL or the LGPL. If you do not delete
33 * the provisions above, a recipient may use your version of this file under
34 * the terms of any one of the MPL, the GPL or the LGPL.
36 * ***** END LICENSE BLOCK ***** */
37 #ifndef nsTableRowGroupFrame_h__
38 #define nsTableRowGroupFrame_h__
40 #include "nscore.h"
41 #include "nsHTMLContainerFrame.h"
42 #include "nsIAtom.h"
43 #include "nsILineIterator.h"
44 #include "nsTablePainter.h"
45 #include "nsTArray.h"
47 class nsTableFrame;
48 class nsTableRowFrame;
49 class nsTableCellFrame;
51 struct nsRowGroupReflowState {
52 const nsHTMLReflowState& reflowState; // Our reflow state
54 nsTableFrame* tableFrame;
56 // The available size (computed from the parent)
57 nsSize availSize;
59 // Running y-offset
60 nscoord y;
62 nsRowGroupReflowState(const nsHTMLReflowState& aReflowState,
63 nsTableFrame* aTableFrame)
64 :reflowState(aReflowState), tableFrame(aTableFrame)
66 availSize.width = reflowState.availableWidth;
67 availSize.height = reflowState.availableHeight;
68 y = 0;
71 ~nsRowGroupReflowState() {}
74 #define NS_ITABLEROWGROUPFRAME_IID \
75 { 0xe940e7bc, 0xb534, 0x11d2, \
76 { 0x95, 0xa2, 0x0, 0x60, 0xb0, 0xc3, 0x44, 0x14 } }
78 // use the following bits from nsFrame's frame state
80 // thead or tfoot should be repeated on every printed page
81 #define NS_ROWGROUP_REPEATABLE 0x80000000
82 #define NS_ROWGROUP_HAS_STYLE_HEIGHT 0x40000000
83 // the next is also used on rows (see nsTableRowGroupFrame::InitRepeatedFrame)
84 #define NS_REPEATED_ROW_OR_ROWGROUP 0x10000000
85 #define NS_ROWGROUP_HAS_ROW_CURSOR 0x08000000
87 #define MIN_ROWS_NEEDING_CURSOR 20
89 /**
90 * nsTableRowGroupFrame is the frame that maps row groups
91 * (HTML tags THEAD, TFOOT, and TBODY). This class cannot be reused
92 * outside of an nsTableFrame. It assumes that its parent is an nsTableFrame, and
93 * its children are nsTableRowFrames.
95 * @see nsTableFrame
96 * @see nsTableRowFrame
98 class nsTableRowGroupFrame : public nsHTMLContainerFrame, public nsILineIteratorNavigator
100 public:
101 // nsISupports
102 NS_DECL_ISUPPORTS_INHERITED
104 /** instantiate a new instance of nsTableRowFrame.
105 * @param aPresShell the pres shell for this frame
107 * @return the frame that was created
109 friend nsIFrame* NS_NewTableRowGroupFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
110 virtual ~nsTableRowGroupFrame();
112 NS_IMETHOD Init(nsIContent* aContent,
113 nsIFrame* aParent,
114 nsIFrame* aPrevInFlow);
116 NS_IMETHOD AppendFrames(nsIAtom* aListName,
117 nsIFrame* aFrameList);
119 NS_IMETHOD InsertFrames(nsIAtom* aListName,
120 nsIFrame* aPrevFrame,
121 nsIFrame* aFrameList);
123 NS_IMETHOD RemoveFrame(nsIAtom* aListName,
124 nsIFrame* aOldFrame);
126 virtual nsMargin GetUsedMargin() const;
127 virtual nsMargin GetUsedBorder() const;
128 virtual nsMargin GetUsedPadding() const;
130 NS_IMETHOD BuildDisplayList(nsDisplayListBuilder* aBuilder,
131 const nsRect& aDirtyRect,
132 const nsDisplayListSet& aLists);
134 /** calls Reflow for all of its child rows.
135 * Rows are all set to the same width and stacked vertically.
136 * <P> rows are not split unless absolutely necessary.
138 * @param aDesiredSize width set to width of rows, height set to
139 * sum of height of rows that fit in aMaxSize.height.
141 * @see nsIFrame::Reflow
143 NS_IMETHOD Reflow(nsPresContext* aPresContext,
144 nsHTMLReflowMetrics& aDesiredSize,
145 const nsHTMLReflowState& aReflowState,
146 nsReflowStatus& aStatus);
149 * Get the "type" of the frame
151 * @see nsGkAtoms::tableRowGroupFrame
153 virtual nsIAtom* GetType() const;
155 virtual PRBool IsContainingBlock() const;
157 nsTableRowFrame* GetFirstRow();
159 #ifdef DEBUG
160 NS_IMETHOD GetFrameName(nsAString& aResult) const;
161 #endif
163 /** return the number of child rows (not necessarily == number of child frames) */
164 PRInt32 GetRowCount();
166 /** return the table-relative row index of the first row in this rowgroup.
167 * if there are no rows, -1 is returned.
169 PRInt32 GetStartRowIndex();
171 /** Adjust the row indices of all rows whose index is >= aRowIndex.
172 * @param aRowIndex - start adjusting with this index
173 * @param aAdjustment - shift the row index by this amount
175 void AdjustRowIndices(PRInt32 aRowIndex,
176 PRInt32 anAdjustment);
179 * Used for header and footer row group frames that are repeated when
180 * splitting a table frame.
182 * Performs any table specific initialization
184 * @param aHeaderFooterFrame the original header or footer row group frame
185 * that was repeated
187 nsresult InitRepeatedFrame(nsPresContext* aPresContext,
188 nsTableRowGroupFrame* aHeaderFooterFrame);
192 * Get the total height of all the row rects
194 nscoord GetHeightBasis(const nsHTMLReflowState& aReflowState);
196 nsMargin* GetBCBorderWidth(nsMargin& aBorder);
199 * Gets inner border widths before collapsing with cell borders
200 * Caller must get top border from previous row group or from table
201 * GetContinuousBCBorderWidth will not overwrite aBorder.top
202 * see nsTablePainter about continuous borders
204 void GetContinuousBCBorderWidth(nsMargin& aBorder);
206 * Sets full border widths before collapsing with cell borders
207 * @param aForSide - side to set; only right, left, and bottom valid
209 void SetContinuousBCBorderWidth(PRUint8 aForSide,
210 BCPixelSize aPixelValue);
212 * Adjust to the effect of visibibility:collapse on the row group and
213 * its children
214 * @return additional shift upward that should be applied to
215 * subsequent rowgroups due to rows and this rowgroup
216 * being collapsed
217 * @param aYTotalOffset the total amount that the rowgroup is shifted up
218 * @param aWidth new width of the rowgroup
220 nscoord CollapseRowGroupIfNecessary(nscoord aYTotalOffset,
221 nscoord aWidth);
223 // nsILineIterator methods
224 public:
225 // The table row is the equivalent to a line in block layout.
226 // The nsILineIterator assumes that a line resides in a block, this role is
227 // fullfilled by the row group. Rows in table are counted relative to the
228 // table. The row index of row corresponds to the cellmap coordinates. The
229 // line index with respect to a row group can be computed by substracting the
230 // row index of the first row in the row group.
232 /** Get the number of rows in a row group
233 * @param aResult - pointer that holds the number of lines in a row group
235 NS_IMETHOD GetNumLines(PRInt32* aResult);
237 /** @see nsILineIterator.h GetDirection
238 * @param aIsRightToLeft - true if the table is rtl
240 NS_IMETHOD GetDirection(PRBool* aIsRightToLeft);
242 /** Return structural information about a line.
243 * @param aLineNumber - the index of the row relative to the row group
244 * If the line-number is invalid then
245 * aFirstFrameOnLine will be nsnull and
246 * aNumFramesOnLine will be zero.
247 * @param aFirstFrameOnLine - the first cell frame that originates in row
248 * with a rowindex that matches a line number
249 * @param aNumFramesOnLine - return the numbers of cells originating in
250 * this row
251 * @param aLineBounds - rect of the row
252 * @param aLineFlags - unused set to 0
254 NS_IMETHOD GetLine(PRInt32 aLineNumber,
255 nsIFrame** aFirstFrameOnLine,
256 PRInt32* aNumFramesOnLine,
257 nsRect& aLineBounds,
258 PRUint32* aLineFlags);
260 /** Given a frame that's a child of the rowgroup, find which line its on.
261 * @param aFrame - frame, should be a row
262 * @param aIndexResult - row index relative to the row group if this a row
263 * frame. aIndexResult will be set to -1 if the frame
264 * cannot be found.
266 NS_IMETHOD FindLineContaining(nsIFrame* aFrame, PRInt32* aLineNumberResult);
268 /** not implemented
269 * the function is also not called in our tree
271 NS_IMETHOD FindLineAt(nscoord aY, PRInt32* aLineNumberResult);
273 /** Find the orginating cell frame on a row that is the nearest to the
274 * coordinate X.
275 * @param aLineNumber - the index of the row relative to the row group
276 * @param aX - X coordinate in twips relative to the
277 * origin of the row group
278 * @param aFrameFound - pointer to the cellframe
279 * @param aXIsBeforeFirstFrame - the point is before the first originating
280 * cellframe
281 * @param aXIsAfterLastFrame - the point is after the last originating
282 * cellframe
284 NS_IMETHOD FindFrameAt(PRInt32 aLineNumber,
285 nscoord aX,
286 nsIFrame** aFrameFound,
287 PRBool* aXIsBeforeFirstFrame,
288 PRBool* aXIsAfterLastFrame);
290 #ifdef IBMBIDI
291 /** Check whether visual and logical order of cell frames within a line are
292 * identical. As the layout will reorder them this is always the case
293 * @param aLine - the index of the row relative to the table
294 * @param aIsReordered - returns false
295 * @param aFirstVisual - if the table is rtl first originating cell frame
296 * @param aLastVisual - if the table is rtl last originating cell frame
299 NS_IMETHOD CheckLineOrder(PRInt32 aLine,
300 PRBool *aIsReordered,
301 nsIFrame **aFirstVisual,
302 nsIFrame **aLastVisual);
303 #endif
305 /** Find the next originating cell frame that originates in the row.
306 * @param aFrame - cell frame to start with, will return the next cell
307 * originating in a row
308 * @param aLineNumber - the index of the row relative to the table
310 NS_IMETHOD GetNextSiblingOnLine(nsIFrame*& aFrame, PRInt32 aLineNumber);
312 // row cursor methods to speed up searching for the row(s)
313 // containing a point. The basic idea is that we set the cursor
314 // property if the rows' y and yMosts are non-decreasing (considering only
315 // rows with nonempty overflowAreas --- empty overflowAreas never participate
316 // in event handling or painting), and the rowgroup has sufficient number of
317 // rows. The cursor property points to a "recently used" row. If we get a
318 // series of requests that work on rows "near" the cursor, then we can find
319 // those nearby rows quickly by starting our search at the cursor.
320 // This code is based on the line cursor code in nsBlockFrame. It's more general
321 // though, and could be extracted and used elsewhere.
322 struct FrameCursorData {
323 nsTArray<nsIFrame*> mFrames;
324 PRUint32 mCursorIndex;
325 nscoord mOverflowAbove;
326 nscoord mOverflowBelow;
328 FrameCursorData()
329 : mFrames(MIN_ROWS_NEEDING_CURSOR), mCursorIndex(0), mOverflowAbove(0),
330 mOverflowBelow(0) {}
332 PRBool AppendFrame(nsIFrame* aFrame);
334 void FinishBuildingCursor() {
335 mFrames.Compact();
339 // Clear out row cursor because we're disturbing the rows (e.g., Reflow)
340 void ClearRowCursor();
343 * Get the first row that might contain y-coord 'aY', or nsnull if you must search
344 * all rows.
345 * The actual row returned might not contain 'aY', but if not, it is guaranteed
346 * to be before any row which does contain 'aY'.
347 * aOverflowAbove is the maximum over all rows of -row.GetOverflowRect().y.
348 * To find all rows that intersect the vertical interval aY/aYMost, call
349 * GetFirstRowContaining(aY, &overflowAbove), and then iterate through all
350 * rows until reaching a row where row->GetRect().y - overflowAbove >= aYMost.
351 * That row and all subsequent rows cannot intersect the interval.
353 nsIFrame* GetFirstRowContaining(nscoord aY, nscoord* aOverflowAbove);
356 * Set up the row cursor. After this, call AppendFrame for every
357 * child frame in sibling order. Ensure that the child frame y and YMost values
358 * form non-decreasing sequences (should always be true for table rows);
359 * if this is violated, call ClearRowCursor(). If we return nsnull, then we
360 * decided not to use a cursor or we already have one set up.
362 FrameCursorData* SetupRowCursor();
364 protected:
365 nsTableRowGroupFrame(nsStyleContext* aContext);
367 void InitChildReflowState(nsPresContext& aPresContext,
368 PRBool aBorderCollapse,
369 nsHTMLReflowState& aReflowState);
371 /** implement abstract method on nsHTMLContainerFrame */
372 virtual PRIntn GetSkipSides() const;
374 void PlaceChild(nsPresContext* aPresContext,
375 nsRowGroupReflowState& aReflowState,
376 nsIFrame* aKidFrame,
377 nsHTMLReflowMetrics& aDesiredSize,
378 const nsRect& aOriginalKidRect);
380 void CalculateRowHeights(nsPresContext* aPresContext,
381 nsHTMLReflowMetrics& aDesiredSize,
382 const nsHTMLReflowState& aReflowState);
384 void DidResizeRows(nsHTMLReflowMetrics& aDesiredSize);
386 void SlideChild(nsRowGroupReflowState& aReflowState,
387 nsIFrame* aKidFrame);
390 * Reflow the frames we've already created
392 * @param aPresContext presentation context to use
393 * @param aReflowState current inline state
394 * @return true if we successfully reflowed all the mapped children and false
395 * otherwise, e.g. we pushed children to the next in flow
397 NS_METHOD ReflowChildren(nsPresContext* aPresContext,
398 nsHTMLReflowMetrics& aDesiredSize,
399 nsRowGroupReflowState& aReflowState,
400 nsReflowStatus& aStatus,
401 PRBool* aPageBreakBeforeEnd = nsnull);
403 nsresult SplitRowGroup(nsPresContext* aPresContext,
404 nsHTMLReflowMetrics& aDesiredSize,
405 const nsHTMLReflowState& aReflowState,
406 nsTableFrame* aTableFrame,
407 nsReflowStatus& aStatus);
409 void SplitSpanningCells(nsPresContext& aPresContext,
410 const nsHTMLReflowState& aReflowState,
411 nsTableFrame& aTableFrame,
412 nsTableRowFrame& aFirstRow,
413 nsTableRowFrame& aLastRow,
414 PRBool aFirstRowIsTopOfPage,
415 nscoord aSpanningRowBottom,
416 nsTableRowFrame*& aContRowFrame,
417 nsTableRowFrame*& aFirstTruncatedRow,
418 nscoord& aDesiredHeight);
420 void CreateContinuingRowFrame(nsPresContext& aPresContext,
421 nsIFrame& aRowFrame,
422 nsIFrame** aContRowFrame);
424 PRBool IsSimpleRowFrame(nsTableFrame* aTableFrame,
425 nsIFrame* aFrame);
427 void GetNextRowSibling(nsIFrame** aRowFrame);
429 void UndoContinuedRow(nsPresContext* aPresContext,
430 nsTableRowFrame* aRow);
432 private:
433 // border widths in pixels in the collapsing border model
434 BCPixelSize mRightContBorderWidth;
435 BCPixelSize mBottomContBorderWidth;
436 BCPixelSize mLeftContBorderWidth;
438 public:
439 virtual nsIFrame* GetFirstFrame() { return mFrames.FirstChild(); }
440 virtual nsIFrame* GetLastFrame() { return mFrames.LastChild(); }
441 virtual void GetNextFrame(nsIFrame* aFrame,
442 nsIFrame** aResult) { *aResult = aFrame->GetNextSibling(); }
443 PRBool IsRepeatable() const;
444 void SetRepeatable(PRBool aRepeatable);
445 PRBool HasStyleHeight() const;
446 void SetHasStyleHeight(PRBool aValue);
450 inline PRBool nsTableRowGroupFrame::IsRepeatable() const
452 return (mState & NS_ROWGROUP_REPEATABLE) == NS_ROWGROUP_REPEATABLE;
455 inline void nsTableRowGroupFrame::SetRepeatable(PRBool aRepeatable)
457 if (aRepeatable) {
458 mState |= NS_ROWGROUP_REPEATABLE;
459 } else {
460 mState &= ~NS_ROWGROUP_REPEATABLE;
464 inline PRBool nsTableRowGroupFrame::HasStyleHeight() const
466 return (mState & NS_ROWGROUP_HAS_STYLE_HEIGHT) == NS_ROWGROUP_HAS_STYLE_HEIGHT;
469 inline void nsTableRowGroupFrame::SetHasStyleHeight(PRBool aValue)
471 if (aValue) {
472 mState |= NS_ROWGROUP_HAS_STYLE_HEIGHT;
473 } else {
474 mState &= ~NS_ROWGROUP_HAS_STYLE_HEIGHT;
478 inline void
479 nsTableRowGroupFrame::GetContinuousBCBorderWidth(nsMargin& aBorder)
481 PRInt32 aPixelsToTwips = nsPresContext::AppUnitsPerCSSPixel();
482 aBorder.right = BC_BORDER_LEFT_HALF_COORD(aPixelsToTwips,
483 mRightContBorderWidth);
484 aBorder.bottom = BC_BORDER_TOP_HALF_COORD(aPixelsToTwips,
485 mBottomContBorderWidth);
486 aBorder.left = BC_BORDER_RIGHT_HALF_COORD(aPixelsToTwips,
487 mLeftContBorderWidth);
488 return;
490 #endif