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
4 : *
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/
9 : *
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.
14 : *
15 : * The Original Code is mozilla.org code.
16 : *
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.
21 : *
22 : * Contributor(s):
23 : *
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.
35 : *
36 : * ***** END LICENSE BLOCK ***** */
37 : #ifndef nsTableRowFrame_h__
38 : #define nsTableRowFrame_h__
39 :
40 : #include "nscore.h"
41 : #include "nsContainerFrame.h"
42 : #include "nsTablePainter.h"
43 :
44 : class nsTableFrame;
45 : class nsTableCellFrame;
46 : struct nsTableCellReflowState;
47 :
48 : // This is also used on rows, from nsTableRowGroupFrame.h
49 : // #define NS_REPEATED_ROW_OR_ROWGROUP NS_FRAME_STATE_BIT(28)
50 :
51 : // Indicates whether this row has any cells that have
52 : // non-auto-height and rowspan=1
53 : #define NS_ROW_HAS_CELL_WITH_STYLE_HEIGHT NS_FRAME_STATE_BIT(29)
54 :
55 : #define NS_TABLE_ROW_HAS_UNPAGINATED_HEIGHT NS_FRAME_STATE_BIT(30)
56 :
57 : /**
58 : * nsTableRowFrame is the frame that maps table rows
59 : * (HTML tag TR). This class cannot be reused
60 : * outside of an nsTableRowGroupFrame. It assumes that its parent is an nsTableRowGroupFrame,
61 : * and its children are nsTableCellFrames.
62 : *
63 : * @see nsTableFrame
64 : * @see nsTableRowGroupFrame
65 : * @see nsTableCellFrame
66 : */
67 : class nsTableRowFrame : public nsContainerFrame
68 : {
69 : public:
70 : NS_DECL_QUERYFRAME_TARGET(nsTableRowFrame)
71 : NS_DECL_QUERYFRAME
72 : NS_DECL_FRAMEARENA_HELPERS
73 :
74 : virtual ~nsTableRowFrame();
75 :
76 : NS_IMETHOD Init(nsIContent* aContent,
77 : nsIFrame* aParent,
78 : nsIFrame* aPrevInFlow);
79 : /** @see nsIFrame::DidSetStyleContext */
80 : virtual void DidSetStyleContext(nsStyleContext* aOldStyleContext);
81 :
82 : NS_IMETHOD AppendFrames(ChildListID aListID,
83 : nsFrameList& aFrameList);
84 : NS_IMETHOD InsertFrames(ChildListID aListID,
85 : nsIFrame* aPrevFrame,
86 : nsFrameList& aFrameList);
87 : NS_IMETHOD RemoveFrame(ChildListID aListID,
88 : nsIFrame* aOldFrame);
89 :
90 : /** instantiate a new instance of nsTableRowFrame.
91 : * @param aPresShell the pres shell for this frame
92 : *
93 : * @return the frame that was created
94 : */
95 : friend nsIFrame* NS_NewTableRowFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
96 :
97 : virtual nsMargin GetUsedMargin() const;
98 : virtual nsMargin GetUsedBorder() const;
99 : virtual nsMargin GetUsedPadding() const;
100 :
101 : NS_IMETHOD BuildDisplayList(nsDisplayListBuilder* aBuilder,
102 : const nsRect& aDirtyRect,
103 : const nsDisplayListSet& aLists);
104 :
105 : nsTableCellFrame* GetFirstCell() ;
106 :
107 : /** calls Reflow for all of its child cells.
108 : * Cells with rowspan=1 are all set to the same height and stacked horizontally.
109 : * <P> Cells are not split unless absolutely necessary.
110 : * <P> Cells are resized in nsTableFrame::BalanceColumnWidths
111 : * and nsTableFrame::ShrinkWrapChildren
112 : *
113 : * @param aDesiredSize width set to width of the sum of the cells, height set to
114 : * height of cells with rowspan=1.
115 : *
116 : * @see nsIFrame::Reflow
117 : * @see nsTableFrame::BalanceColumnWidths
118 : * @see nsTableFrame::ShrinkWrapChildren
119 : */
120 : NS_IMETHOD Reflow(nsPresContext* aPresContext,
121 : nsHTMLReflowMetrics& aDesiredSize,
122 : const nsHTMLReflowState& aReflowState,
123 : nsReflowStatus& aStatus);
124 :
125 : void DidResize();
126 :
127 : /**
128 : * Get the "type" of the frame
129 : *
130 : * @see nsGkAtoms::tableRowFrame
131 : */
132 : virtual nsIAtom* GetType() const;
133 :
134 : #ifdef DEBUG
135 : NS_IMETHOD GetFrameName(nsAString& aResult) const;
136 : #endif
137 :
138 : void UpdateHeight(nscoord aHeight,
139 : nscoord aAscent,
140 : nscoord aDescent,
141 : nsTableFrame* aTableFrame = nsnull,
142 : nsTableCellFrame* aCellFrame = nsnull);
143 :
144 : void ResetHeight(nscoord aRowStyleHeight);
145 :
146 : // calculate the height, considering content height of the
147 : // cells and the style height of the row and cells, excluding pct heights
148 : nscoord CalcHeight(const nsHTMLReflowState& aReflowState);
149 :
150 : // Support for cells with 'vertical-align: baseline'.
151 :
152 : /**
153 : * returns the max-ascent amongst all the cells that have
154 : * 'vertical-align: baseline', *including* cells with rowspans.
155 : * returns 0 if we don't have any cell with 'vertical-align: baseline'
156 : */
157 : nscoord GetMaxCellAscent() const;
158 :
159 : /* return the row ascent
160 : */
161 : nscoord GetRowBaseline();
162 :
163 : /** returns the ordinal position of this row in its table */
164 : virtual PRInt32 GetRowIndex() const;
165 :
166 : /** set this row's starting row index */
167 : void SetRowIndex (int aRowIndex);
168 :
169 : /** used by row group frame code */
170 : nscoord ReflowCellFrame(nsPresContext* aPresContext,
171 : const nsHTMLReflowState& aReflowState,
172 : bool aIsTopOfPage,
173 : nsTableCellFrame* aCellFrame,
174 : nscoord aAvailableHeight,
175 : nsReflowStatus& aStatus);
176 : /**
177 : * Collapse the row if required, apply col and colgroup visibility: collapse
178 : * info to the cells in the row.
179 : * @return he amount to shift up all following rows
180 : * @param aRowOffset - shift the row up by this amount
181 : * @param aWidth - new width of the row
182 : * @param aCollapseGroup - parent rowgroup is collapsed so this row needs
183 : * to be collapsed
184 : * @param aDidCollapse - the row has been collapsed
185 : */
186 : nscoord CollapseRowIfNecessary(nscoord aRowOffset,
187 : nscoord aWidth,
188 : bool aCollapseGroup,
189 : bool& aDidCollapse);
190 :
191 : /**
192 : * Insert a cell frame after the last cell frame that has a col index
193 : * that is less than aColIndex. If no such cell frame is found the
194 : * frame to insert is prepended to the child list.
195 : * @param aFrame the cell frame to insert
196 : * @param aColIndex the col index
197 : */
198 : void InsertCellFrame(nsTableCellFrame* aFrame,
199 : PRInt32 aColIndex);
200 :
201 : nsresult CalculateCellActualHeight(nsTableCellFrame* aCellFrame,
202 : nscoord& aDesiredHeight);
203 :
204 : bool IsFirstInserted() const;
205 : void SetFirstInserted(bool aValue);
206 :
207 : nscoord GetContentHeight() const;
208 : void SetContentHeight(nscoord aTwipValue);
209 :
210 : bool HasStyleHeight() const;
211 :
212 : bool HasFixedHeight() const;
213 : void SetHasFixedHeight(bool aValue);
214 :
215 : bool HasPctHeight() const;
216 : void SetHasPctHeight(bool aValue);
217 :
218 : nscoord GetFixedHeight() const;
219 : void SetFixedHeight(nscoord aValue);
220 :
221 : float GetPctHeight() const;
222 : void SetPctHeight(float aPctValue,
223 : bool aForce = false);
224 :
225 : nscoord GetHeight(nscoord aBasis = 0) const;
226 :
227 : nsTableRowFrame* GetNextRow() const;
228 :
229 : bool HasUnpaginatedHeight();
230 : void SetHasUnpaginatedHeight(bool aValue);
231 : nscoord GetUnpaginatedHeight(nsPresContext* aPresContext);
232 : void SetUnpaginatedHeight(nsPresContext* aPresContext, nscoord aValue);
233 :
234 : nscoord GetTopBCBorderWidth();
235 : void SetTopBCBorderWidth(BCPixelSize aWidth);
236 : nscoord GetBottomBCBorderWidth();
237 : void SetBottomBCBorderWidth(BCPixelSize aWidth);
238 : nsMargin* GetBCBorderWidth(nsMargin& aBorder);
239 :
240 : /**
241 : * Gets inner border widths before collapsing with cell borders
242 : * Caller must get bottom border from next row or from table
243 : * GetContinuousBCBorderWidth will not overwrite aBorder.bottom
244 : * see nsTablePainter about continuous borders
245 : */
246 : void GetContinuousBCBorderWidth(nsMargin& aBorder);
247 : /**
248 : * @returns outer top bc border == prev row's bottom inner
249 : */
250 : nscoord GetOuterTopContBCBorderWidth();
251 : /**
252 : * Sets full border widths before collapsing with cell borders
253 : * @param aForSide - side to set; only accepts right, left, and top
254 : */
255 : void SetContinuousBCBorderWidth(PRUint8 aForSide,
256 : BCPixelSize aPixelValue);
257 :
258 : protected:
259 :
260 : /** protected constructor.
261 : * @see NewFrame
262 : */
263 : nsTableRowFrame(nsStyleContext *aContext);
264 :
265 : void InitChildReflowState(nsPresContext& aPresContext,
266 : const nsSize& aAvailSize,
267 : bool aBorderCollapse,
268 : nsTableCellReflowState& aReflowState);
269 :
270 : /** implement abstract method on nsContainerFrame */
271 : virtual PRIntn GetSkipSides() const;
272 :
273 : // row-specific methods
274 :
275 : nscoord ComputeCellXOffset(const nsHTMLReflowState& aState,
276 : nsIFrame* aKidFrame,
277 : const nsMargin& aKidMargin) const;
278 : /**
279 : * Called for incremental/dirty and resize reflows. If aDirtyOnly is true then
280 : * only reflow dirty cells.
281 : */
282 : nsresult ReflowChildren(nsPresContext* aPresContext,
283 : nsHTMLReflowMetrics& aDesiredSize,
284 : const nsHTMLReflowState& aReflowState,
285 : nsTableFrame& aTableFrame,
286 : nsReflowStatus& aStatus);
287 :
288 : private:
289 : struct RowBits {
290 : unsigned mRowIndex:29;
291 : unsigned mHasFixedHeight:1; // set if the dominating style height on the row or any cell is pixel based
292 : unsigned mHasPctHeight:1; // set if the dominating style height on the row or any cell is pct based
293 : unsigned mFirstInserted:1; // if true, then it was the top most newly inserted row
294 : } mBits;
295 :
296 : // the desired height based on the content of the tallest cell in the row
297 : nscoord mContentHeight;
298 : // the height based on a style percentage height on either the row or any cell
299 : // if mHasPctHeight is set
300 : nscoord mStylePctHeight;
301 : // the height based on a style pixel height on the row or any
302 : // cell if mHasFixedHeight is set
303 : nscoord mStyleFixedHeight;
304 :
305 : // max-ascent and max-descent amongst all cells that have 'vertical-align: baseline'
306 : nscoord mMaxCellAscent; // does include cells with rowspan > 1
307 : nscoord mMaxCellDescent; // does *not* include cells with rowspan > 1
308 :
309 : // border widths in pixels in the collapsing border model of the *inner*
310 : // half of the border only
311 : BCPixelSize mTopBorderWidth;
312 : BCPixelSize mBottomBorderWidth;
313 : BCPixelSize mRightContBorderWidth;
314 : BCPixelSize mTopContBorderWidth;
315 : BCPixelSize mLeftContBorderWidth;
316 :
317 : /**
318 : * Sets the NS_ROW_HAS_CELL_WITH_STYLE_HEIGHT bit to indicate whether
319 : * this row has any cells that have non-auto-height. (Row-spanning
320 : * cells are ignored.)
321 : */
322 : void InitHasCellWithStyleHeight(nsTableFrame* aTableFrame);
323 :
324 : };
325 :
326 0 : inline PRInt32 nsTableRowFrame::GetRowIndex() const
327 : {
328 0 : return PRInt32(mBits.mRowIndex);
329 : }
330 :
331 0 : inline void nsTableRowFrame::SetRowIndex (int aRowIndex)
332 : {
333 0 : mBits.mRowIndex = aRowIndex;
334 0 : }
335 :
336 0 : inline bool nsTableRowFrame::IsFirstInserted() const
337 : {
338 0 : return bool(mBits.mFirstInserted);
339 : }
340 :
341 0 : inline void nsTableRowFrame::SetFirstInserted(bool aValue)
342 : {
343 0 : mBits.mFirstInserted = aValue;
344 0 : }
345 :
346 0 : inline bool nsTableRowFrame::HasStyleHeight() const
347 : {
348 0 : return (bool)mBits.mHasFixedHeight || (bool)mBits.mHasPctHeight;
349 : }
350 :
351 0 : inline bool nsTableRowFrame::HasFixedHeight() const
352 : {
353 0 : return (bool)mBits.mHasFixedHeight;
354 : }
355 :
356 0 : inline void nsTableRowFrame::SetHasFixedHeight(bool aValue)
357 : {
358 0 : mBits.mHasFixedHeight = aValue;
359 0 : }
360 :
361 0 : inline bool nsTableRowFrame::HasPctHeight() const
362 : {
363 0 : return (bool)mBits.mHasPctHeight;
364 : }
365 :
366 0 : inline void nsTableRowFrame::SetHasPctHeight(bool aValue)
367 : {
368 0 : mBits.mHasPctHeight = aValue;
369 0 : }
370 :
371 0 : inline nscoord nsTableRowFrame::GetContentHeight() const
372 : {
373 0 : return mContentHeight;
374 : }
375 :
376 0 : inline void nsTableRowFrame::SetContentHeight(nscoord aValue)
377 : {
378 0 : mContentHeight = aValue;
379 0 : }
380 :
381 0 : inline nscoord nsTableRowFrame::GetFixedHeight() const
382 : {
383 0 : if (mBits.mHasFixedHeight)
384 0 : return mStyleFixedHeight;
385 : else
386 0 : return 0;
387 : }
388 :
389 0 : inline float nsTableRowFrame::GetPctHeight() const
390 : {
391 0 : if (mBits.mHasPctHeight)
392 0 : return (float)mStylePctHeight / 100.0f;
393 : else
394 0 : return 0.0f;
395 : }
396 :
397 0 : inline bool nsTableRowFrame::HasUnpaginatedHeight()
398 : {
399 : return (mState & NS_TABLE_ROW_HAS_UNPAGINATED_HEIGHT) ==
400 0 : NS_TABLE_ROW_HAS_UNPAGINATED_HEIGHT;
401 : }
402 :
403 0 : inline void nsTableRowFrame::SetHasUnpaginatedHeight(bool aValue)
404 : {
405 0 : if (aValue) {
406 0 : mState |= NS_TABLE_ROW_HAS_UNPAGINATED_HEIGHT;
407 : } else {
408 0 : mState &= ~NS_TABLE_ROW_HAS_UNPAGINATED_HEIGHT;
409 : }
410 0 : }
411 :
412 0 : inline nscoord nsTableRowFrame::GetTopBCBorderWidth()
413 : {
414 0 : return mTopBorderWidth;
415 : }
416 :
417 0 : inline void nsTableRowFrame::SetTopBCBorderWidth(BCPixelSize aWidth)
418 : {
419 0 : mTopBorderWidth = aWidth;
420 0 : }
421 :
422 0 : inline nscoord nsTableRowFrame::GetBottomBCBorderWidth()
423 : {
424 0 : return mBottomBorderWidth;
425 : }
426 :
427 0 : inline void nsTableRowFrame::SetBottomBCBorderWidth(BCPixelSize aWidth)
428 : {
429 0 : mBottomBorderWidth = aWidth;
430 0 : }
431 :
432 0 : inline nsMargin* nsTableRowFrame::GetBCBorderWidth(nsMargin& aBorder)
433 : {
434 0 : aBorder.left = aBorder.right = 0;
435 :
436 0 : aBorder.top = nsPresContext::CSSPixelsToAppUnits(mTopBorderWidth);
437 0 : aBorder.bottom = nsPresContext::CSSPixelsToAppUnits(mBottomBorderWidth);
438 :
439 0 : return &aBorder;
440 : }
441 :
442 : inline void
443 0 : nsTableRowFrame::GetContinuousBCBorderWidth(nsMargin& aBorder)
444 : {
445 0 : PRInt32 aPixelsToTwips = nsPresContext::AppUnitsPerCSSPixel();
446 : aBorder.right = BC_BORDER_LEFT_HALF_COORD(aPixelsToTwips,
447 0 : mLeftContBorderWidth);
448 : aBorder.top = BC_BORDER_BOTTOM_HALF_COORD(aPixelsToTwips,
449 0 : mTopContBorderWidth);
450 : aBorder.left = BC_BORDER_RIGHT_HALF_COORD(aPixelsToTwips,
451 0 : mRightContBorderWidth);
452 0 : }
453 :
454 0 : inline nscoord nsTableRowFrame::GetOuterTopContBCBorderWidth()
455 : {
456 0 : PRInt32 aPixelsToTwips = nsPresContext::AppUnitsPerCSSPixel();
457 0 : return BC_BORDER_TOP_HALF_COORD(aPixelsToTwips, mTopContBorderWidth);
458 : }
459 :
460 : #endif
|