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