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 nsTableCellFrame_h__
38 : #define nsTableCellFrame_h__
39 :
40 : #include "nsITableCellLayout.h"
41 : #include "nscore.h"
42 : #include "nsContainerFrame.h"
43 : #include "nsTableRowFrame.h" // need to actually include this here to inline GetRowIndex
44 : #include "nsStyleContext.h"
45 : #include "nsIPercentHeightObserver.h"
46 : #include "nsGkAtoms.h"
47 : #include "nsLayoutUtils.h"
48 : #include "nsTArray.h"
49 :
50 : class nsTableFrame;
51 :
52 : /**
53 : * Additional frame-state bits
54 : */
55 : #define NS_TABLE_CELL_CONTENT_EMPTY NS_FRAME_STATE_BIT(31)
56 : #define NS_TABLE_CELL_HAD_SPECIAL_REFLOW NS_FRAME_STATE_BIT(29)
57 : #define NS_TABLE_CELL_HAS_PCT_OVER_HEIGHT NS_FRAME_STATE_BIT(28)
58 :
59 : /**
60 : * nsTableCellFrame
61 : * data structure to maintain information about a single table cell's frame
62 : *
63 : * NOTE: frames are not ref counted. We expose addref and release here
64 : * so we can change that decsion in the future. Users of nsITableCellLayout
65 : * should refcount correctly as if this object is being ref counted, though
66 : * no actual support is under the hood.
67 : *
68 : * @author sclark
69 : */
70 : class nsTableCellFrame : public nsContainerFrame,
71 : public nsITableCellLayout,
72 : public nsIPercentHeightObserver
73 : {
74 : public:
75 : NS_DECL_QUERYFRAME_TARGET(nsTableCellFrame)
76 : NS_DECL_QUERYFRAME
77 : NS_DECL_FRAMEARENA_HELPERS
78 :
79 : // default constructor supplied by the compiler
80 :
81 : nsTableCellFrame(nsStyleContext* aContext);
82 : ~nsTableCellFrame();
83 :
84 : NS_IMETHOD Init(nsIContent* aContent,
85 : nsIFrame* aParent,
86 : nsIFrame* aPrevInFlow);
87 :
88 : #ifdef ACCESSIBILITY
89 : virtual already_AddRefed<nsAccessible> CreateAccessible();
90 : #endif
91 :
92 : NS_IMETHOD AttributeChanged(PRInt32 aNameSpaceID,
93 : nsIAtom* aAttribute,
94 : PRInt32 aModType);
95 :
96 : /** @see nsIFrame::DidSetStyleContext */
97 : virtual void DidSetStyleContext(nsStyleContext* aOldStyleContext);
98 :
99 : // table cells contain a block frame which does most of the work, and
100 : // so these functions should never be called. They assert and return
101 : // NS_ERROR_NOT_IMPLEMENTED
102 : NS_IMETHOD AppendFrames(ChildListID aListID,
103 : nsFrameList& aFrameList);
104 : NS_IMETHOD InsertFrames(ChildListID aListID,
105 : nsIFrame* aPrevFrame,
106 : nsFrameList& aFrameList);
107 : NS_IMETHOD RemoveFrame(ChildListID aListID,
108 : nsIFrame* aOldFrame);
109 :
110 0 : virtual nsIFrame* GetContentInsertionFrame() {
111 0 : return GetFirstPrincipalChild()->GetContentInsertionFrame();
112 : }
113 :
114 : virtual nsMargin GetUsedMargin() const;
115 :
116 : virtual void NotifyPercentHeight(const nsHTMLReflowState& aReflowState);
117 :
118 : virtual bool NeedsToObserve(const nsHTMLReflowState& aReflowState);
119 :
120 : /** instantiate a new instance of nsTableRowFrame.
121 : * @param aPresShell the pres shell for this frame
122 : *
123 : * @return the frame that was created
124 : */
125 : friend nsIFrame* NS_NewTableCellFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
126 :
127 : NS_IMETHOD BuildDisplayList(nsDisplayListBuilder* aBuilder,
128 : const nsRect& aDirtyRect,
129 : const nsDisplayListSet& aLists);
130 :
131 : void PaintCellBackground(nsRenderingContext& aRenderingContext,
132 : const nsRect& aDirtyRect, nsPoint aPt,
133 : PRUint32 aFlags);
134 :
135 : virtual nscoord GetMinWidth(nsRenderingContext *aRenderingContext);
136 : virtual nscoord GetPrefWidth(nsRenderingContext *aRenderingContext);
137 : virtual IntrinsicWidthOffsetData
138 : IntrinsicWidthOffsets(nsRenderingContext* aRenderingContext);
139 :
140 : NS_IMETHOD Reflow(nsPresContext* aPresContext,
141 : nsHTMLReflowMetrics& aDesiredSize,
142 : const nsHTMLReflowState& aReflowState,
143 : nsReflowStatus& aStatus);
144 :
145 : /**
146 : * Get the "type" of the frame
147 : *
148 : * @see nsLayoutAtoms::tableCellFrame
149 : */
150 : virtual nsIAtom* GetType() const;
151 :
152 : #ifdef DEBUG
153 : NS_IMETHOD GetFrameName(nsAString& aResult) const;
154 : #endif
155 :
156 : void VerticallyAlignChild(nscoord aMaxAscent);
157 :
158 : /*
159 : * Get the value of vertical-align adjusted for CSS 2's rules for a
160 : * table cell, which means the result is always
161 : * NS_STYLE_VERTICAL_ALIGN_{TOP,MIDDLE,BOTTOM,BASELINE}.
162 : */
163 : PRUint8 GetVerticalAlign() const;
164 :
165 0 : bool HasVerticalAlignBaseline() const {
166 0 : return GetVerticalAlign() == NS_STYLE_VERTICAL_ALIGN_BASELINE;
167 : }
168 :
169 : bool CellHasVisibleContent(nscoord height,
170 : nsTableFrame* tableFrame,
171 : nsIFrame* kidFrame);
172 :
173 : /**
174 : * Get the first-line baseline of the cell relative to its top border
175 : * edge, as if the cell were vertically aligned to the top of the row.
176 : */
177 : nscoord GetCellBaseline() const;
178 :
179 : /**
180 : * return the cell's specified row span. this is what was specified in the
181 : * content model or in the style info, and is always >= 1.
182 : * to get the effective row span (the actual value that applies), use GetEffectiveRowSpan()
183 : * @see nsTableFrame::GetEffectiveRowSpan()
184 : */
185 : virtual PRInt32 GetRowSpan();
186 :
187 : // there is no set row index because row index depends on the cell's parent row only
188 :
189 : /*---------------- nsITableCellLayout methods ------------------------*/
190 :
191 : /**
192 : * return the cell's starting row index (starting at 0 for the first row).
193 : * for continued cell frames the row index is that of the cell's first-in-flow
194 : * and the column index (starting at 0 for the first column
195 : */
196 : NS_IMETHOD GetCellIndexes(PRInt32 &aRowIndex, PRInt32 &aColIndex);
197 :
198 : /** return the mapped cell's row index (starting at 0 for the first row) */
199 : virtual nsresult GetRowIndex(PRInt32 &aRowIndex) const;
200 :
201 : /**
202 : * return the cell's specified col span. this is what was specified in the
203 : * content model or in the style info, and is always >= 1.
204 : * to get the effective col span (the actual value that applies), use GetEffectiveColSpan()
205 : * @see nsTableFrame::GetEffectiveColSpan()
206 : */
207 : virtual PRInt32 GetColSpan();
208 :
209 : /** return the cell's column index (starting at 0 for the first column) */
210 : virtual nsresult GetColIndex(PRInt32 &aColIndex) const;
211 : void SetColIndex(PRInt32 aColIndex);
212 :
213 : /** return the available width given to this frame during its last reflow */
214 : inline nscoord GetPriorAvailWidth();
215 :
216 : /** set the available width given to this frame during its last reflow */
217 : inline void SetPriorAvailWidth(nscoord aPriorAvailWidth);
218 :
219 : /** return the desired size returned by this frame during its last reflow */
220 : inline nsSize GetDesiredSize();
221 :
222 : /** set the desired size returned by this frame during its last reflow */
223 : inline void SetDesiredSize(const nsHTMLReflowMetrics & aDesiredSize);
224 :
225 : bool GetContentEmpty();
226 : void SetContentEmpty(bool aContentEmpty);
227 :
228 : bool HasPctOverHeight();
229 : void SetHasPctOverHeight(bool aValue);
230 :
231 : nsTableCellFrame* GetNextCell() const;
232 :
233 : virtual nsMargin* GetBorderWidth(nsMargin& aBorder) const;
234 :
235 : virtual void PaintBackground(nsRenderingContext& aRenderingContext,
236 : const nsRect& aDirtyRect,
237 : nsPoint aPt,
238 : PRUint32 aFlags);
239 :
240 : void DecorateForSelection(nsRenderingContext& aRenderingContext,
241 : nsPoint aPt);
242 :
243 : virtual bool UpdateOverflow();
244 :
245 : protected:
246 : /** implement abstract method on nsContainerFrame */
247 : virtual PRIntn GetSkipSides() const;
248 :
249 : /**
250 : * GetBorderOverflow says how far the cell's own borders extend
251 : * outside its own bounds. In the separated borders model this should
252 : * just be zero (as it is for most frames), but in the collapsed
253 : * borders model (for which nsBCTableCellFrame overrides this virtual
254 : * method), it considers the extents of the collapsed border.
255 : */
256 : virtual nsMargin GetBorderOverflow();
257 :
258 : friend class nsTableRowFrame;
259 :
260 : PRUint32 mColIndex; // the starting column for this cell
261 :
262 : nscoord mPriorAvailWidth; // the avail width during the last reflow
263 : nsSize mDesiredSize; // the last desired width & height
264 : };
265 :
266 0 : inline nscoord nsTableCellFrame::GetPriorAvailWidth()
267 0 : { return mPriorAvailWidth;}
268 :
269 0 : inline void nsTableCellFrame::SetPriorAvailWidth(nscoord aPriorAvailWidth)
270 0 : { mPriorAvailWidth = aPriorAvailWidth;}
271 :
272 0 : inline nsSize nsTableCellFrame::GetDesiredSize()
273 0 : { return mDesiredSize; }
274 :
275 0 : inline void nsTableCellFrame::SetDesiredSize(const nsHTMLReflowMetrics & aDesiredSize)
276 : {
277 0 : mDesiredSize.width = aDesiredSize.width;
278 0 : mDesiredSize.height = aDesiredSize.height;
279 0 : }
280 :
281 0 : inline bool nsTableCellFrame::GetContentEmpty()
282 : {
283 : return (mState & NS_TABLE_CELL_CONTENT_EMPTY) ==
284 0 : NS_TABLE_CELL_CONTENT_EMPTY;
285 : }
286 :
287 0 : inline void nsTableCellFrame::SetContentEmpty(bool aContentEmpty)
288 : {
289 0 : if (aContentEmpty) {
290 0 : mState |= NS_TABLE_CELL_CONTENT_EMPTY;
291 : } else {
292 0 : mState &= ~NS_TABLE_CELL_CONTENT_EMPTY;
293 : }
294 0 : }
295 :
296 : inline bool nsTableCellFrame::HasPctOverHeight()
297 : {
298 : return (mState & NS_TABLE_CELL_HAS_PCT_OVER_HEIGHT) ==
299 : NS_TABLE_CELL_HAS_PCT_OVER_HEIGHT;
300 : }
301 :
302 0 : inline void nsTableCellFrame::SetHasPctOverHeight(bool aValue)
303 : {
304 0 : if (aValue) {
305 0 : mState |= NS_TABLE_CELL_HAS_PCT_OVER_HEIGHT;
306 : } else {
307 0 : mState &= ~NS_TABLE_CELL_HAS_PCT_OVER_HEIGHT;
308 : }
309 0 : }
310 :
311 : // nsBCTableCellFrame
312 : class nsBCTableCellFrame : public nsTableCellFrame
313 : {
314 : public:
315 : NS_DECL_FRAMEARENA_HELPERS
316 :
317 : nsBCTableCellFrame(nsStyleContext* aContext);
318 :
319 : ~nsBCTableCellFrame();
320 :
321 : virtual nsIAtom* GetType() const;
322 :
323 : virtual nsMargin GetUsedBorder() const;
324 : virtual bool GetBorderRadii(nscoord aRadii[8]) const;
325 :
326 : // Get the *inner half of the border only*, in twips.
327 : virtual nsMargin* GetBorderWidth(nsMargin& aBorder) const;
328 :
329 : // Get the *inner half of the border only*, in pixels.
330 : BCPixelSize GetBorderWidth(mozilla::css::Side aSide) const;
331 :
332 : // Set the full (both halves) width of the border
333 : void SetBorderWidth(mozilla::css::Side aSide, BCPixelSize aPixelValue);
334 :
335 : virtual nsMargin GetBorderOverflow();
336 :
337 : #ifdef DEBUG
338 : NS_IMETHOD GetFrameName(nsAString& aResult) const;
339 : #endif
340 :
341 : virtual void PaintBackground(nsRenderingContext& aRenderingContext,
342 : const nsRect& aDirtyRect,
343 : nsPoint aPt,
344 : PRUint32 aFlags);
345 :
346 : private:
347 :
348 : // These are the entire width of the border (the cell edge contains only
349 : // the inner half, per the macros in nsTablePainter.h).
350 : BCPixelSize mTopBorder;
351 : BCPixelSize mRightBorder;
352 : BCPixelSize mBottomBorder;
353 : BCPixelSize mLeftBorder;
354 : };
355 :
356 : #endif
|