Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(111)

Side by Side Diff: third_party/WebKit/Source/core/css/cssom/CSSCalcLength.cpp

Issue 2867883003: [CSS Typed OM] Delete obsolete number and length classes from Typed OM (Closed)
Patch Set: rebase Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "core/css/cssom/CSSCalcLength.h"
6
7 #include "bindings/core/v8/ExceptionState.h"
8 #include "core/css/CSSCalculationValue.h"
9 #include "core/css/CSSPrimitiveValue.h"
10 #include "core/css/cssom/CSSCalcDictionary.h"
11 #include "core/css/cssom/CSSSimpleLength.h"
12 #include "platform/wtf/Vector.h"
13
14 namespace blink {
15
16 namespace {
17
18 static CSSPrimitiveValue::UnitType UnitFromIndex(int index) {
19 DCHECK(index < CSSLengthValue::kNumSupportedUnits);
20 int lowest_value = static_cast<int>(CSSPrimitiveValue::UnitType::kPercentage);
21 return static_cast<CSSPrimitiveValue::UnitType>(index + lowest_value);
22 }
23
24 int IndexForUnit(CSSPrimitiveValue::UnitType unit) {
25 return (static_cast<int>(unit) -
26 static_cast<int>(CSSPrimitiveValue::UnitType::kPercentage));
27 }
28
29 } // namespace
30
31 CSSCalcLength::CSSCalcLength(const CSSCalcLength& other)
32 : unit_data_(other.unit_data_) {}
33
34 CSSCalcLength::CSSCalcLength(const CSSSimpleLength& other) {
35 unit_data_.Set(other.LengthUnit(), other.value());
36 }
37
38 CSSCalcLength* CSSCalcLength::Create(const CSSLengthValue* length) {
39 if (length->GetType() == kSimpleLengthType) {
40 const CSSSimpleLength* simple_length = ToCSSSimpleLength(length);
41 return new CSSCalcLength(*simple_length);
42 }
43
44 return new CSSCalcLength(*ToCSSCalcLength(length));
45 }
46
47 CSSCalcLength* CSSCalcLength::Create(const CSSCalcDictionary& dictionary,
48 ExceptionState& exception_state) {
49 int num_set = 0;
50 UnitData result;
51
52 #define SET_FROM_DICT_VALUE(name, camelName, primitiveName) \
53 if (dictionary.has##camelName()) { \
54 result.Set(CSSPrimitiveValue::UnitType::primitiveName, dictionary.name()); \
55 num_set++; \
56 }
57
58 SET_FROM_DICT_VALUE(px, Px, kPixels)
59 SET_FROM_DICT_VALUE(percent, Percent, kPercentage)
60 SET_FROM_DICT_VALUE(em, Em, kEms)
61 SET_FROM_DICT_VALUE(ex, Ex, kExs)
62 SET_FROM_DICT_VALUE(ch, Ch, kChs)
63 SET_FROM_DICT_VALUE(rem, Rem, kRems)
64 SET_FROM_DICT_VALUE(vw, Vw, kViewportWidth)
65 SET_FROM_DICT_VALUE(vh, Vh, kViewportHeight)
66 SET_FROM_DICT_VALUE(vmin, Vmin, kViewportMin)
67 SET_FROM_DICT_VALUE(vmax, Vmax, kViewportMax)
68 SET_FROM_DICT_VALUE(cm, Cm, kCentimeters)
69 SET_FROM_DICT_VALUE(mm, Mm, kMillimeters)
70 SET_FROM_DICT_VALUE(in, In, kInches)
71 SET_FROM_DICT_VALUE(pc, Pc, kPicas)
72 SET_FROM_DICT_VALUE(pt, Pt, kPoints)
73
74 #undef SET_FROM_DICT_VALUE
75
76 if (num_set == 0) {
77 exception_state.ThrowTypeError(
78 "Must specify at least one value in CSSCalcDictionary for creating a "
79 "CSSCalcLength.");
80 return nullptr;
81 }
82 return new CSSCalcLength(result);
83 }
84
85 CSSCalcLength* CSSCalcLength::FromCSSValue(const CSSPrimitiveValue& value) {
86 std::unique_ptr<UnitData> unit_data =
87 UnitData::FromExpressionNode(value.CssCalcValue()->ExpressionNode());
88 if (unit_data)
89 return new CSSCalcLength(*unit_data);
90 return nullptr;
91 }
92
93 CSSCalcLength* CSSCalcLength::FromLength(const Length& length) {
94 DCHECK(length.IsCalculated());
95 PixelsAndPercent values = length.GetPixelsAndPercent();
96 UnitData unit_data;
97 unit_data.Set(CSSPrimitiveValue::UnitType::kPixels, values.pixels);
98 unit_data.Set(CSSPrimitiveValue::UnitType::kPercentage, values.percent);
99 CSSCalcLength* result = new CSSCalcLength(unit_data);
100 return result;
101 }
102
103 bool CSSCalcLength::ContainsPercent() const {
104 return unit_data_.Has(CSSPrimitiveValue::UnitType::kPercentage);
105 }
106
107 CSSLengthValue* CSSCalcLength::AddInternal(const CSSLengthValue* other) {
108 UnitData result = unit_data_;
109 if (other->GetType() == kSimpleLengthType) {
110 const CSSSimpleLength* simple_length = ToCSSSimpleLength(other);
111 result.Set(
112 simple_length->LengthUnit(),
113 unit_data_.Get(simple_length->LengthUnit()) + simple_length->value());
114 } else {
115 result.Add(ToCSSCalcLength(other)->unit_data_);
116 }
117 return new CSSCalcLength(result);
118 }
119
120 CSSLengthValue* CSSCalcLength::SubtractInternal(const CSSLengthValue* other) {
121 UnitData result = unit_data_;
122 if (other->GetType() == kSimpleLengthType) {
123 const CSSSimpleLength* simple_length = ToCSSSimpleLength(other);
124 result.Set(
125 simple_length->LengthUnit(),
126 unit_data_.Get(simple_length->LengthUnit()) - simple_length->value());
127 } else {
128 result.Subtract(ToCSSCalcLength(other)->unit_data_);
129 }
130 return new CSSCalcLength(result);
131 }
132
133 CSSLengthValue* CSSCalcLength::MultiplyInternal(double x) {
134 UnitData result = unit_data_;
135 result.Multiply(x);
136 return new CSSCalcLength(result);
137 }
138
139 CSSLengthValue* CSSCalcLength::DivideInternal(double x) {
140 UnitData result = unit_data_;
141 result.Divide(x);
142 return new CSSCalcLength(result);
143 }
144
145 CSSValue* CSSCalcLength::ToCSSValue() const {
146 CSSCalcExpressionNode* node = unit_data_.ToCSSCalcExpressionNode();
147 if (node)
148 return CSSPrimitiveValue::Create(CSSCalcValue::Create(node));
149 return nullptr;
150 }
151
152 std::unique_ptr<CSSCalcLength::UnitData>
153 CSSCalcLength::UnitData::FromExpressionNode(
154 const CSSCalcExpressionNode* expression_node) {
155 CalculationCategory category = expression_node->Category();
156 DCHECK(category == CalculationCategory::kCalcLength ||
157 category == CalculationCategory::kCalcPercentLength ||
158 category == CalculationCategory::kCalcPercent);
159
160 if (expression_node->GetType() ==
161 CSSCalcExpressionNode::Type::kCssCalcPrimitiveValue) {
162 CSSPrimitiveValue::UnitType unit = expression_node->TypeWithCalcResolved();
163 DCHECK(CSSLengthValue::IsSupportedLengthUnit(unit));
164 std::unique_ptr<UnitData> result(new UnitData());
165 result->Set(unit, expression_node->DoubleValue());
166 return result;
167 }
168
169 const CSSCalcExpressionNode* left = expression_node->LeftExpressionNode();
170 const CSSCalcExpressionNode* right = expression_node->RightExpressionNode();
171 CalcOperator op = expression_node->OperatorType();
172
173 if (op == kCalcMultiply) {
174 std::unique_ptr<UnitData> unit_data = nullptr;
175 double argument = 0;
176 // One side should be a number.
177 if (left->Category() == CalculationCategory::kCalcNumber) {
178 unit_data = UnitData::FromExpressionNode(right);
179 argument = left->DoubleValue();
180 } else if (right->Category() == CalculationCategory::kCalcNumber) {
181 unit_data = UnitData::FromExpressionNode(left);
182 argument = right->DoubleValue();
183 } else {
184 NOTREACHED();
185 return nullptr;
186 }
187 DCHECK(unit_data);
188 unit_data->Multiply(argument);
189 return unit_data;
190 }
191
192 if (op == kCalcDivide) {
193 // Divisor must always be on the RHS.
194 DCHECK_EQ(right->Category(), CalculationCategory::kCalcNumber);
195 std::unique_ptr<UnitData> unit_data = UnitData::FromExpressionNode(left);
196 DCHECK(unit_data);
197 unit_data->Divide(right->DoubleValue());
198 return unit_data;
199 }
200
201 // Add and subtract.
202 std::unique_ptr<UnitData> left_unit_data = UnitData::FromExpressionNode(left);
203 std::unique_ptr<UnitData> right_unit_data =
204 UnitData::FromExpressionNode(right);
205 DCHECK(left_unit_data);
206 DCHECK(right_unit_data);
207
208 if (op == kCalcAdd)
209 left_unit_data->Add(*right_unit_data);
210 else if (op == kCalcSubtract)
211 left_unit_data->Subtract(*right_unit_data);
212 else
213 NOTREACHED();
214
215 return left_unit_data;
216 }
217
218 CSSCalcExpressionNode* CSSCalcLength::UnitData::ToCSSCalcExpressionNode()
219 const {
220 CSSCalcExpressionNode* node = nullptr;
221 for (unsigned i = 0; i < CSSLengthValue::kNumSupportedUnits; ++i) {
222 if (!HasAtIndex(i))
223 continue;
224 double value = GetAtIndex(i);
225 if (node) {
226 node = CSSCalcValue::CreateExpressionNode(
227 node,
228 CSSCalcValue::CreateExpressionNode(
229 CSSPrimitiveValue::Create(std::abs(value), UnitFromIndex(i))),
230 value >= 0 ? kCalcAdd : kCalcSubtract);
231 } else {
232 node = CSSCalcValue::CreateExpressionNode(
233 CSSPrimitiveValue::Create(value, UnitFromIndex(i)));
234 }
235 }
236 return node;
237 }
238
239 bool CSSCalcLength::UnitData::HasAtIndex(int i) const {
240 DCHECK_GE(i, 0);
241 DCHECK_LT(i, CSSLengthValue::kNumSupportedUnits);
242 return has_value_for_unit_[i];
243 }
244
245 bool CSSCalcLength::UnitData::Has(CSSPrimitiveValue::UnitType unit) const {
246 return HasAtIndex(IndexForUnit(unit));
247 }
248
249 void CSSCalcLength::UnitData::SetAtIndex(int i, double value) {
250 DCHECK_GE(i, 0);
251 DCHECK_LT(i, CSSLengthValue::kNumSupportedUnits);
252 has_value_for_unit_.set(i);
253 values_[i] = value;
254 }
255
256 void CSSCalcLength::UnitData::Set(CSSPrimitiveValue::UnitType unit,
257 double value) {
258 SetAtIndex(IndexForUnit(unit), value);
259 }
260
261 double CSSCalcLength::UnitData::GetAtIndex(int i) const {
262 DCHECK_GE(i, 0);
263 DCHECK_LT(i, CSSLengthValue::kNumSupportedUnits);
264 return values_[i];
265 }
266
267 double CSSCalcLength::UnitData::Get(CSSPrimitiveValue::UnitType unit) const {
268 return GetAtIndex(IndexForUnit(unit));
269 }
270
271 void CSSCalcLength::UnitData::Add(const CSSCalcLength::UnitData& right) {
272 for (int i = 0; i < CSSLengthValue::kNumSupportedUnits; ++i) {
273 if (right.HasAtIndex(i)) {
274 SetAtIndex(i, GetAtIndex(i) + right.GetAtIndex(i));
275 }
276 }
277 }
278
279 void CSSCalcLength::UnitData::Subtract(const CSSCalcLength::UnitData& right) {
280 for (int i = 0; i < CSSLengthValue::kNumSupportedUnits; ++i) {
281 if (right.HasAtIndex(i)) {
282 SetAtIndex(i, GetAtIndex(i) - right.GetAtIndex(i));
283 }
284 }
285 }
286
287 void CSSCalcLength::UnitData::Multiply(double x) {
288 for (int i = 0; i < CSSLengthValue::kNumSupportedUnits; ++i) {
289 if (HasAtIndex(i)) {
290 SetAtIndex(i, GetAtIndex(i) * x);
291 }
292 }
293 }
294
295 void CSSCalcLength::UnitData::Divide(double x) {
296 DCHECK_NE(x, 0);
297 for (int i = 0; i < CSSLengthValue::kNumSupportedUnits; ++i) {
298 if (HasAtIndex(i)) {
299 SetAtIndex(i, GetAtIndex(i) / x);
300 }
301 }
302 }
303
304 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/css/cssom/CSSCalcLength.h ('k') | third_party/WebKit/Source/core/css/cssom/CSSCalcLength.idl » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698