|
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 nsTableColFrame_h__ |
|
6 #define nsTableColFrame_h__ |
|
7 |
|
8 #include "mozilla/Attributes.h" |
|
9 #include "celldata.h" |
|
10 #include "nscore.h" |
|
11 #include "nsContainerFrame.h" |
|
12 #include "nsTArray.h" |
|
13 |
|
14 class nsTableCellFrame; |
|
15 |
|
16 enum nsTableColType { |
|
17 eColContent = 0, // there is real col content associated |
|
18 eColAnonymousCol = 1, // the result of a span on a col |
|
19 eColAnonymousColGroup = 2, // the result of a span on a col group |
|
20 eColAnonymousCell = 3 // the result of a cell alone |
|
21 }; |
|
22 |
|
23 class nsTableColFrame : public nsSplittableFrame { |
|
24 public: |
|
25 NS_DECL_FRAMEARENA_HELPERS |
|
26 |
|
27 enum {eWIDTH_SOURCE_NONE =0, // no cell has contributed to the width style |
|
28 eWIDTH_SOURCE_CELL =1, // a cell specified a width |
|
29 eWIDTH_SOURCE_CELL_WITH_SPAN=2 // a cell implicitly specified a width via colspan |
|
30 }; |
|
31 |
|
32 nsTableColType GetColType() const; |
|
33 void SetColType(nsTableColType aType); |
|
34 |
|
35 /** instantiate a new instance of nsTableRowFrame. |
|
36 * @param aPresShell the pres shell for this frame |
|
37 * |
|
38 * @return the frame that was created |
|
39 */ |
|
40 friend nsTableColFrame* NS_NewTableColFrame(nsIPresShell* aPresShell, |
|
41 nsStyleContext* aContext); |
|
42 /** @see nsIFrame::DidSetStyleContext */ |
|
43 virtual void DidSetStyleContext(nsStyleContext* aOldStyleContext) MOZ_OVERRIDE; |
|
44 |
|
45 int32_t GetColIndex() const; |
|
46 |
|
47 void SetColIndex (int32_t aColIndex); |
|
48 |
|
49 nsTableColFrame* GetNextCol() const; |
|
50 |
|
51 virtual nsresult Reflow(nsPresContext* aPresContext, |
|
52 nsHTMLReflowMetrics& aDesiredSize, |
|
53 const nsHTMLReflowState& aReflowState, |
|
54 nsReflowStatus& aStatus) MOZ_OVERRIDE; |
|
55 |
|
56 /** |
|
57 * Table columns never paint anything, nor receive events. |
|
58 */ |
|
59 virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, |
|
60 const nsRect& aDirtyRect, |
|
61 const nsDisplayListSet& aLists) MOZ_OVERRIDE {} |
|
62 |
|
63 /** |
|
64 * Get the "type" of the frame |
|
65 * |
|
66 * @see nsGkAtoms::tableColFrame |
|
67 */ |
|
68 virtual nsIAtom* GetType() const MOZ_OVERRIDE; |
|
69 |
|
70 #ifdef DEBUG_FRAME_DUMP |
|
71 virtual nsresult GetFrameName(nsAString& aResult) const MOZ_OVERRIDE; |
|
72 #endif |
|
73 |
|
74 virtual nsSplittableType GetSplittableType() const MOZ_OVERRIDE; |
|
75 |
|
76 /** return the number of the columns the col represents. always >= 1 */ |
|
77 int32_t GetSpan(); |
|
78 |
|
79 /** convenience method, calls into cellmap */ |
|
80 int32_t Count() const; |
|
81 |
|
82 nscoord GetLeftBorderWidth(); |
|
83 void SetLeftBorderWidth(BCPixelSize aWidth); |
|
84 nscoord GetRightBorderWidth(); |
|
85 void SetRightBorderWidth(BCPixelSize aWidth); |
|
86 |
|
87 /** |
|
88 * Gets inner border widths before collapsing with cell borders |
|
89 * Caller must get left border from previous column or from table |
|
90 * GetContinuousBCBorderWidth will not overwrite aBorder.left |
|
91 * see nsTablePainter about continuous borders |
|
92 * |
|
93 * @return outer right border width (left inner for next column) |
|
94 */ |
|
95 nscoord GetContinuousBCBorderWidth(nsMargin& aBorder); |
|
96 /** |
|
97 * Set full border widths before collapsing with cell borders |
|
98 * @param aForSide - side to set; only valid for top, right, and bottom |
|
99 */ |
|
100 void SetContinuousBCBorderWidth(uint8_t aForSide, |
|
101 BCPixelSize aPixelValue); |
|
102 #ifdef DEBUG |
|
103 void Dump(int32_t aIndent); |
|
104 #endif |
|
105 |
|
106 /** |
|
107 * Restore the default values of the intrinsic widths, so that we can |
|
108 * re-accumulate intrinsic widths from the cells in the column. |
|
109 */ |
|
110 void ResetIntrinsics() { |
|
111 mMinCoord = 0; |
|
112 mPrefCoord = 0; |
|
113 mPrefPercent = 0.0f; |
|
114 mHasSpecifiedCoord = false; |
|
115 } |
|
116 |
|
117 /** |
|
118 * Restore the default value of the preferred percentage width (the |
|
119 * only intrinsic width used by FixedTableLayoutStrategy. |
|
120 */ |
|
121 void ResetPrefPercent() { |
|
122 mPrefPercent = 0.0f; |
|
123 } |
|
124 |
|
125 /** |
|
126 * Restore the default values of the temporary buffer for |
|
127 * spanning-cell intrinsic widths (as we process spanning cells). |
|
128 */ |
|
129 void ResetSpanIntrinsics() { |
|
130 mSpanMinCoord = 0; |
|
131 mSpanPrefCoord = 0; |
|
132 mSpanPrefPercent = 0.0f; |
|
133 } |
|
134 |
|
135 /** |
|
136 * Add the widths for a cell or column element, or the contribution of |
|
137 * the widths from a column-spanning cell: |
|
138 * @param aMinCoord The minimum intrinsic width |
|
139 * @param aPrefCoord The preferred intrinsic width or, if there is a |
|
140 * specified non-percentage width, max(specified width, minimum intrinsic |
|
141 * width). |
|
142 * @param aHasSpecifiedCoord Whether there is a specified |
|
143 * non-percentage width. |
|
144 * |
|
145 * Note that the implementation of this functions is a bit tricky |
|
146 * since mPrefCoord means different things depending on |
|
147 * whether mHasSpecifiedCoord is true (and likewise for aPrefCoord and |
|
148 * aHasSpecifiedCoord). If mHasSpecifiedCoord is false, then |
|
149 * all widths added had aHasSpecifiedCoord false and mPrefCoord is the |
|
150 * largest of the pref widths. But if mHasSpecifiedCoord is true, |
|
151 * then mPrefCoord is the largest of (1) the pref widths for cells |
|
152 * with aHasSpecifiedCoord true and (2) the min widths for cells with |
|
153 * aHasSpecifiedCoord false. |
|
154 */ |
|
155 void AddCoords(nscoord aMinCoord, nscoord aPrefCoord, |
|
156 bool aHasSpecifiedCoord) { |
|
157 NS_ASSERTION(aMinCoord <= aPrefCoord, "intrinsic widths out of order"); |
|
158 |
|
159 if (aHasSpecifiedCoord && !mHasSpecifiedCoord) { |
|
160 mPrefCoord = mMinCoord; |
|
161 mHasSpecifiedCoord = true; |
|
162 } |
|
163 if (!aHasSpecifiedCoord && mHasSpecifiedCoord) { |
|
164 aPrefCoord = aMinCoord; // NOTE: modifying argument |
|
165 } |
|
166 |
|
167 if (aMinCoord > mMinCoord) |
|
168 mMinCoord = aMinCoord; |
|
169 if (aPrefCoord > mPrefCoord) |
|
170 mPrefCoord = aPrefCoord; |
|
171 |
|
172 NS_ASSERTION(mMinCoord <= mPrefCoord, "min larger than pref"); |
|
173 } |
|
174 |
|
175 /** |
|
176 * Add a percentage width specified on a cell or column element or the |
|
177 * contribution to this column of a percentage width specified on a |
|
178 * column-spanning cell. |
|
179 */ |
|
180 void AddPrefPercent(float aPrefPercent) { |
|
181 if (aPrefPercent > mPrefPercent) |
|
182 mPrefPercent = aPrefPercent; |
|
183 } |
|
184 |
|
185 /** |
|
186 * Get the largest minimum intrinsic width for this column. |
|
187 */ |
|
188 nscoord GetMinCoord() const { return mMinCoord; } |
|
189 /** |
|
190 * Get the largest preferred width for this column, or, if there were |
|
191 * any specified non-percentage widths (see GetHasSpecifiedCoord), the |
|
192 * largest minimum intrinsic width or specified width. |
|
193 */ |
|
194 nscoord GetPrefCoord() const { return mPrefCoord; } |
|
195 /** |
|
196 * Get whether there were any specified widths contributing to this |
|
197 * column. |
|
198 */ |
|
199 bool GetHasSpecifiedCoord() const { return mHasSpecifiedCoord; } |
|
200 |
|
201 /** |
|
202 * Get the largest specified percentage width contributing to this |
|
203 * column (returns 0 if there were none). |
|
204 */ |
|
205 float GetPrefPercent() const { return mPrefPercent; } |
|
206 |
|
207 /** |
|
208 * Like AddCoords, but into a temporary buffer used for groups of |
|
209 * column-spanning cells. |
|
210 */ |
|
211 void AddSpanCoords(nscoord aSpanMinCoord, nscoord aSpanPrefCoord, |
|
212 bool aSpanHasSpecifiedCoord) { |
|
213 NS_ASSERTION(aSpanMinCoord <= aSpanPrefCoord, |
|
214 "intrinsic widths out of order"); |
|
215 |
|
216 if (!aSpanHasSpecifiedCoord && mHasSpecifiedCoord) { |
|
217 aSpanPrefCoord = aSpanMinCoord; // NOTE: modifying argument |
|
218 } |
|
219 |
|
220 if (aSpanMinCoord > mSpanMinCoord) |
|
221 mSpanMinCoord = aSpanMinCoord; |
|
222 if (aSpanPrefCoord > mSpanPrefCoord) |
|
223 mSpanPrefCoord = aSpanPrefCoord; |
|
224 |
|
225 NS_ASSERTION(mSpanMinCoord <= mSpanPrefCoord, "min larger than pref"); |
|
226 } |
|
227 |
|
228 /* |
|
229 * Accumulate percentage widths on column spanning cells into |
|
230 * temporary variables. |
|
231 */ |
|
232 void AddSpanPrefPercent(float aSpanPrefPercent) { |
|
233 if (aSpanPrefPercent > mSpanPrefPercent) |
|
234 mSpanPrefPercent = aSpanPrefPercent; |
|
235 } |
|
236 |
|
237 /* |
|
238 * Accumulate the temporary variables for column spanning cells into |
|
239 * the primary variables. |
|
240 */ |
|
241 void AccumulateSpanIntrinsics() { |
|
242 AddCoords(mSpanMinCoord, mSpanPrefCoord, mHasSpecifiedCoord); |
|
243 AddPrefPercent(mSpanPrefPercent); |
|
244 } |
|
245 |
|
246 // Used to adjust a column's pref percent so that the table's total |
|
247 // never exceeeds 100% (by only allowing percentages to be used, |
|
248 // starting at the first column, until they reach 100%). |
|
249 void AdjustPrefPercent(float *aTableTotalPercent) { |
|
250 float allowed = 1.0f - *aTableTotalPercent; |
|
251 if (mPrefPercent > allowed) |
|
252 mPrefPercent = allowed; |
|
253 *aTableTotalPercent += mPrefPercent; |
|
254 } |
|
255 |
|
256 // The final width of the column. |
|
257 void ResetFinalWidth() { |
|
258 mFinalWidth = nscoord_MIN; // so we detect that it changed |
|
259 } |
|
260 void SetFinalWidth(nscoord aFinalWidth) { |
|
261 mFinalWidth = aFinalWidth; |
|
262 } |
|
263 nscoord GetFinalWidth() { |
|
264 return mFinalWidth; |
|
265 } |
|
266 |
|
267 virtual bool IsFrameOfType(uint32_t aFlags) const MOZ_OVERRIDE |
|
268 { |
|
269 return nsSplittableFrame::IsFrameOfType(aFlags & ~(nsIFrame::eTablePart)); |
|
270 } |
|
271 |
|
272 virtual void InvalidateFrame(uint32_t aDisplayItemKey = 0) MOZ_OVERRIDE; |
|
273 virtual void InvalidateFrameWithRect(const nsRect& aRect, uint32_t aDisplayItemKey = 0) MOZ_OVERRIDE; |
|
274 virtual void InvalidateFrameForRemoval() MOZ_OVERRIDE { InvalidateFrameSubtree(); } |
|
275 |
|
276 protected: |
|
277 |
|
278 nsTableColFrame(nsStyleContext* aContext); |
|
279 ~nsTableColFrame(); |
|
280 |
|
281 nscoord mMinCoord; |
|
282 nscoord mPrefCoord; |
|
283 nscoord mSpanMinCoord; // XXX... |
|
284 nscoord mSpanPrefCoord; // XXX... |
|
285 float mPrefPercent; |
|
286 float mSpanPrefPercent; // XXX... |
|
287 // ...XXX the four members marked above could be allocated as part of |
|
288 // a separate array allocated only during |
|
289 // BasicTableLayoutStrategy::ComputeColumnIntrinsicWidths (and only |
|
290 // when colspans were present). |
|
291 nscoord mFinalWidth; |
|
292 |
|
293 // the index of the column with respect to the whole table (starting at 0) |
|
294 // it should never be smaller then the start column index of the parent |
|
295 // colgroup |
|
296 uint32_t mColIndex; |
|
297 |
|
298 // border width in pixels of the inner half of the border only |
|
299 BCPixelSize mLeftBorderWidth; |
|
300 BCPixelSize mRightBorderWidth; |
|
301 BCPixelSize mTopContBorderWidth; |
|
302 BCPixelSize mRightContBorderWidth; |
|
303 BCPixelSize mBottomContBorderWidth; |
|
304 |
|
305 bool mHasSpecifiedCoord; |
|
306 }; |
|
307 |
|
308 inline int32_t nsTableColFrame::GetColIndex() const |
|
309 { |
|
310 return mColIndex; |
|
311 } |
|
312 |
|
313 inline void nsTableColFrame::SetColIndex (int32_t aColIndex) |
|
314 { |
|
315 mColIndex = aColIndex; |
|
316 } |
|
317 |
|
318 inline nscoord nsTableColFrame::GetLeftBorderWidth() |
|
319 { |
|
320 return mLeftBorderWidth; |
|
321 } |
|
322 |
|
323 inline void nsTableColFrame::SetLeftBorderWidth(BCPixelSize aWidth) |
|
324 { |
|
325 mLeftBorderWidth = aWidth; |
|
326 } |
|
327 |
|
328 inline nscoord nsTableColFrame::GetRightBorderWidth() |
|
329 { |
|
330 return mRightBorderWidth; |
|
331 } |
|
332 |
|
333 inline void nsTableColFrame::SetRightBorderWidth(BCPixelSize aWidth) |
|
334 { |
|
335 mRightBorderWidth = aWidth; |
|
336 } |
|
337 |
|
338 inline nscoord |
|
339 nsTableColFrame::GetContinuousBCBorderWidth(nsMargin& aBorder) |
|
340 { |
|
341 int32_t aPixelsToTwips = nsPresContext::AppUnitsPerCSSPixel(); |
|
342 aBorder.top = BC_BORDER_BOTTOM_HALF_COORD(aPixelsToTwips, |
|
343 mTopContBorderWidth); |
|
344 aBorder.right = BC_BORDER_LEFT_HALF_COORD(aPixelsToTwips, |
|
345 mRightContBorderWidth); |
|
346 aBorder.bottom = BC_BORDER_TOP_HALF_COORD(aPixelsToTwips, |
|
347 mBottomContBorderWidth); |
|
348 return BC_BORDER_RIGHT_HALF_COORD(aPixelsToTwips, mRightContBorderWidth); |
|
349 } |
|
350 |
|
351 #endif |
|
352 |