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