|
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 #include "nsCOMPtr.h" |
|
6 #include "nsTableColFrame.h" |
|
7 #include "nsTableFrame.h" |
|
8 #include "nsContainerFrame.h" |
|
9 #include "nsStyleContext.h" |
|
10 #include "nsStyleConsts.h" |
|
11 #include "nsPresContext.h" |
|
12 #include "nsGkAtoms.h" |
|
13 #include "nsCSSRendering.h" |
|
14 #include "nsIContent.h" |
|
15 |
|
16 #define COL_TYPE_BITS (NS_FRAME_STATE_BIT(28) | \ |
|
17 NS_FRAME_STATE_BIT(29) | \ |
|
18 NS_FRAME_STATE_BIT(30) | \ |
|
19 NS_FRAME_STATE_BIT(31)) |
|
20 #define COL_TYPE_OFFSET 28 |
|
21 |
|
22 nsTableColFrame::nsTableColFrame(nsStyleContext* aContext) : |
|
23 nsSplittableFrame(aContext) |
|
24 { |
|
25 SetColType(eColContent); |
|
26 ResetIntrinsics(); |
|
27 ResetSpanIntrinsics(); |
|
28 ResetFinalWidth(); |
|
29 } |
|
30 |
|
31 nsTableColFrame::~nsTableColFrame() |
|
32 { |
|
33 } |
|
34 |
|
35 nsTableColType |
|
36 nsTableColFrame::GetColType() const |
|
37 { |
|
38 return (nsTableColType)((mState & COL_TYPE_BITS) >> COL_TYPE_OFFSET); |
|
39 } |
|
40 |
|
41 void |
|
42 nsTableColFrame::SetColType(nsTableColType aType) |
|
43 { |
|
44 NS_ASSERTION(aType != eColAnonymousCol || |
|
45 (GetPrevContinuation() && |
|
46 GetPrevContinuation()->GetNextContinuation() == this && |
|
47 GetPrevContinuation()->GetNextSibling() == this), |
|
48 "spanned content cols must be continuations"); |
|
49 uint32_t type = aType - eColContent; |
|
50 RemoveStateBits(COL_TYPE_BITS); |
|
51 AddStateBits(nsFrameState(type << COL_TYPE_OFFSET)); |
|
52 } |
|
53 |
|
54 /* virtual */ void |
|
55 nsTableColFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext) |
|
56 { |
|
57 nsSplittableFrame::DidSetStyleContext(aOldStyleContext); |
|
58 |
|
59 if (!aOldStyleContext) //avoid this on init |
|
60 return; |
|
61 |
|
62 nsTableFrame* tableFrame = nsTableFrame::GetTableFrame(this); |
|
63 if (tableFrame->IsBorderCollapse() && |
|
64 tableFrame->BCRecalcNeeded(aOldStyleContext, StyleContext())) { |
|
65 nsIntRect damageArea(GetColIndex(), 0, 1, tableFrame->GetRowCount()); |
|
66 tableFrame->AddBCDamageArea(damageArea); |
|
67 } |
|
68 } |
|
69 |
|
70 void nsTableColFrame::SetContinuousBCBorderWidth(uint8_t aForSide, |
|
71 BCPixelSize aPixelValue) |
|
72 { |
|
73 switch (aForSide) { |
|
74 case NS_SIDE_TOP: |
|
75 mTopContBorderWidth = aPixelValue; |
|
76 return; |
|
77 case NS_SIDE_RIGHT: |
|
78 mRightContBorderWidth = aPixelValue; |
|
79 return; |
|
80 case NS_SIDE_BOTTOM: |
|
81 mBottomContBorderWidth = aPixelValue; |
|
82 return; |
|
83 default: |
|
84 NS_ERROR("invalid side arg"); |
|
85 } |
|
86 } |
|
87 |
|
88 nsresult nsTableColFrame::Reflow(nsPresContext* aPresContext, |
|
89 nsHTMLReflowMetrics& aDesiredSize, |
|
90 const nsHTMLReflowState& aReflowState, |
|
91 nsReflowStatus& aStatus) |
|
92 { |
|
93 DO_GLOBAL_REFLOW_COUNT("nsTableColFrame"); |
|
94 DISPLAY_REFLOW(aPresContext, this, aReflowState, aDesiredSize, aStatus); |
|
95 aDesiredSize.Width() = 0; |
|
96 aDesiredSize.Height() = 0; |
|
97 const nsStyleVisibility* colVis = StyleVisibility(); |
|
98 bool collapseCol = (NS_STYLE_VISIBILITY_COLLAPSE == colVis->mVisible); |
|
99 if (collapseCol) { |
|
100 nsTableFrame* tableFrame = nsTableFrame::GetTableFrame(this); |
|
101 tableFrame->SetNeedToCollapse(true); |
|
102 } |
|
103 aStatus = NS_FRAME_COMPLETE; |
|
104 NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize); |
|
105 return NS_OK; |
|
106 } |
|
107 |
|
108 int32_t nsTableColFrame::GetSpan() |
|
109 { |
|
110 return StyleTable()->mSpan; |
|
111 } |
|
112 |
|
113 #ifdef DEBUG |
|
114 void nsTableColFrame::Dump(int32_t aIndent) |
|
115 { |
|
116 char* indent = new char[aIndent + 1]; |
|
117 if (!indent) return; |
|
118 for (int32_t i = 0; i < aIndent + 1; i++) { |
|
119 indent[i] = ' '; |
|
120 } |
|
121 indent[aIndent] = 0; |
|
122 |
|
123 printf("%s**START COL DUMP**\n%s colIndex=%d coltype=", |
|
124 indent, indent, mColIndex); |
|
125 nsTableColType colType = GetColType(); |
|
126 switch (colType) { |
|
127 case eColContent: |
|
128 printf(" content "); |
|
129 break; |
|
130 case eColAnonymousCol: |
|
131 printf(" anonymous-column "); |
|
132 break; |
|
133 case eColAnonymousColGroup: |
|
134 printf(" anonymous-colgroup "); |
|
135 break; |
|
136 case eColAnonymousCell: |
|
137 printf(" anonymous-cell "); |
|
138 break; |
|
139 } |
|
140 printf("\nm:%d c:%d(%c) p:%f sm:%d sc:%d sp:%f f:%d", |
|
141 int32_t(mMinCoord), int32_t(mPrefCoord), |
|
142 mHasSpecifiedCoord ? 's' : 'u', mPrefPercent, |
|
143 int32_t(mSpanMinCoord), int32_t(mSpanPrefCoord), |
|
144 mSpanPrefPercent, |
|
145 int32_t(GetFinalWidth())); |
|
146 printf("\n%s**END COL DUMP** ", indent); |
|
147 delete [] indent; |
|
148 } |
|
149 #endif |
|
150 /* ----- global methods ----- */ |
|
151 |
|
152 nsTableColFrame* |
|
153 NS_NewTableColFrame(nsIPresShell* aPresShell, nsStyleContext* aContext) |
|
154 { |
|
155 return new (aPresShell) nsTableColFrame(aContext); |
|
156 } |
|
157 |
|
158 NS_IMPL_FRAMEARENA_HELPERS(nsTableColFrame) |
|
159 |
|
160 nsTableColFrame* |
|
161 nsTableColFrame::GetNextCol() const |
|
162 { |
|
163 nsIFrame* childFrame = GetNextSibling(); |
|
164 while (childFrame) { |
|
165 if (nsGkAtoms::tableColFrame == childFrame->GetType()) { |
|
166 return (nsTableColFrame*)childFrame; |
|
167 } |
|
168 childFrame = childFrame->GetNextSibling(); |
|
169 } |
|
170 return nullptr; |
|
171 } |
|
172 |
|
173 nsIAtom* |
|
174 nsTableColFrame::GetType() const |
|
175 { |
|
176 return nsGkAtoms::tableColFrame; |
|
177 } |
|
178 |
|
179 #ifdef DEBUG_FRAME_DUMP |
|
180 nsresult |
|
181 nsTableColFrame::GetFrameName(nsAString& aResult) const |
|
182 { |
|
183 return MakeFrameName(NS_LITERAL_STRING("TableCol"), aResult); |
|
184 } |
|
185 #endif |
|
186 |
|
187 nsSplittableType |
|
188 nsTableColFrame::GetSplittableType() const |
|
189 { |
|
190 return NS_FRAME_NOT_SPLITTABLE; |
|
191 } |
|
192 |
|
193 void |
|
194 nsTableColFrame::InvalidateFrame(uint32_t aDisplayItemKey) |
|
195 { |
|
196 nsIFrame::InvalidateFrame(aDisplayItemKey); |
|
197 GetParent()->InvalidateFrameWithRect(GetVisualOverflowRect() + GetPosition(), aDisplayItemKey); |
|
198 } |
|
199 |
|
200 void |
|
201 nsTableColFrame::InvalidateFrameWithRect(const nsRect& aRect, uint32_t aDisplayItemKey) |
|
202 { |
|
203 nsIFrame::InvalidateFrameWithRect(aRect, aDisplayItemKey); |
|
204 |
|
205 // If we have filters applied that would affects our bounds, then |
|
206 // we get an inactive layer created and this is computed |
|
207 // within FrameLayerBuilder |
|
208 GetParent()->InvalidateFrameWithRect(aRect + GetPosition(), aDisplayItemKey); |
|
209 } |
|
210 |