1 // Copyright 2014 PDFium 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 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6
7 #include "core/fxcrt/css/cfx_cssdeclaration.h"
8
9 #include <cmath>
10 #include <utility>
11
12 #include "core/fxcrt/css/cfx_csscolorvalue.h"
13 #include "core/fxcrt/css/cfx_csscustomproperty.h"
14 #include "core/fxcrt/css/cfx_cssenumvalue.h"
15 #include "core/fxcrt/css/cfx_cssnumbervalue.h"
16 #include "core/fxcrt/css/cfx_csspropertyholder.h"
17 #include "core/fxcrt/css/cfx_cssstringvalue.h"
18 #include "core/fxcrt/css/cfx_cssvaluelist.h"
19 #include "core/fxcrt/css/cfx_cssvaluelistparser.h"
20 #include "core/fxcrt/fx_extension.h"
21 #include "third_party/base/logging.h"
22 #include "third_party/base/ptr_util.h"
23
24 namespace {
25
Hex2Dec(uint8_t hexHigh,uint8_t hexLow)26 uint8_t Hex2Dec(uint8_t hexHigh, uint8_t hexLow) {
27 return (FXSYS_HexCharToInt(hexHigh) << 4) + FXSYS_HexCharToInt(hexLow);
28 }
29
ParseCSSNumber(const wchar_t * pszValue,int32_t iValueLen,float * pValue,CFX_CSSNumberType * pOutUnit)30 bool ParseCSSNumber(const wchar_t* pszValue,
31 int32_t iValueLen,
32 float* pValue,
33 CFX_CSSNumberType* pOutUnit) {
34 ASSERT(pszValue);
35 ASSERT(iValueLen > 0);
36
37 int32_t iUsedLen = 0;
38 *pValue = FXSYS_wcstof(pszValue, iValueLen, &iUsedLen);
39 if (iUsedLen <= 0 || !std::isfinite(*pValue))
40 return false;
41
42 iValueLen -= iUsedLen;
43 pszValue += iUsedLen;
44 *pOutUnit = CFX_CSSNumberType::Number;
45 if (iValueLen >= 1 && *pszValue == '%') {
46 *pOutUnit = CFX_CSSNumberType::Percent;
47 } else if (iValueLen == 2) {
48 const CFX_CSSData::LengthUnit* pUnit =
49 CFX_CSSData::GetLengthUnitByName(WideStringView(pszValue, 2));
50 if (pUnit)
51 *pOutUnit = pUnit->type;
52 }
53 return true;
54 }
55
56 } // namespace
57
58 // static
ParseCSSString(const wchar_t * pszValue,int32_t iValueLen,int32_t * iOffset,int32_t * iLength)59 bool CFX_CSSDeclaration::ParseCSSString(const wchar_t* pszValue,
60 int32_t iValueLen,
61 int32_t* iOffset,
62 int32_t* iLength) {
63 ASSERT(pszValue);
64 ASSERT(iValueLen > 0);
65
66 *iOffset = 0;
67 *iLength = iValueLen;
68 if (iValueLen >= 2) {
69 wchar_t first = pszValue[0], last = pszValue[iValueLen - 1];
70 if ((first == '\"' && last == '\"') || (first == '\'' && last == '\'')) {
71 *iOffset = 1;
72 *iLength -= 2;
73 }
74 }
75 return iValueLen > 0;
76 }
77
78 // static.
ParseCSSColor(const wchar_t * pszValue,int32_t iValueLen,FX_ARGB * dwColor)79 bool CFX_CSSDeclaration::ParseCSSColor(const wchar_t* pszValue,
80 int32_t iValueLen,
81 FX_ARGB* dwColor) {
82 ASSERT(pszValue);
83 ASSERT(iValueLen > 0);
84 ASSERT(dwColor);
85
86 if (*pszValue == '#') {
87 switch (iValueLen) {
88 case 4: {
89 uint8_t red = Hex2Dec((uint8_t)pszValue[1], (uint8_t)pszValue[1]);
90 uint8_t green = Hex2Dec((uint8_t)pszValue[2], (uint8_t)pszValue[2]);
91 uint8_t blue = Hex2Dec((uint8_t)pszValue[3], (uint8_t)pszValue[3]);
92 *dwColor = ArgbEncode(255, red, green, blue);
93 return true;
94 }
95 case 7: {
96 uint8_t red = Hex2Dec((uint8_t)pszValue[1], (uint8_t)pszValue[2]);
97 uint8_t green = Hex2Dec((uint8_t)pszValue[3], (uint8_t)pszValue[4]);
98 uint8_t blue = Hex2Dec((uint8_t)pszValue[5], (uint8_t)pszValue[6]);
99 *dwColor = ArgbEncode(255, red, green, blue);
100 return true;
101 }
102 default:
103 return false;
104 }
105 }
106
107 if (iValueLen >= 10) {
108 if (pszValue[iValueLen - 1] != ')' || FXSYS_wcsnicmp(L"rgb(", pszValue, 4))
109 return false;
110
111 uint8_t rgb[3] = {0};
112 float fValue;
113 CFX_CSSPrimitiveType eType;
114 CFX_CSSValueListParser list(pszValue + 4, iValueLen - 5, ',');
115 for (int32_t i = 0; i < 3; ++i) {
116 if (!list.NextValue(&eType, &pszValue, &iValueLen))
117 return false;
118 if (eType != CFX_CSSPrimitiveType::Number)
119 return false;
120 CFX_CSSNumberType eNumType;
121 if (!ParseCSSNumber(pszValue, iValueLen, &fValue, &eNumType))
122 return false;
123
124 rgb[i] = eNumType == CFX_CSSNumberType::Percent
125 ? FXSYS_roundf(fValue * 2.55f)
126 : FXSYS_roundf(fValue);
127 }
128 *dwColor = ArgbEncode(255, rgb[0], rgb[1], rgb[2]);
129 return true;
130 }
131
132 const CFX_CSSData::Color* pColor =
133 CFX_CSSData::GetColorByName(WideStringView(pszValue, iValueLen));
134 if (!pColor)
135 return false;
136
137 *dwColor = pColor->value;
138 return true;
139 }
140
CFX_CSSDeclaration()141 CFX_CSSDeclaration::CFX_CSSDeclaration() {}
142
~CFX_CSSDeclaration()143 CFX_CSSDeclaration::~CFX_CSSDeclaration() {}
144
GetProperty(CFX_CSSProperty eProperty,bool * bImportant) const145 RetainPtr<CFX_CSSValue> CFX_CSSDeclaration::GetProperty(
146 CFX_CSSProperty eProperty,
147 bool* bImportant) const {
148 for (const auto& p : properties_) {
149 if (p->eProperty == eProperty) {
150 *bImportant = p->bImportant;
151 return p->pValue;
152 }
153 }
154 return nullptr;
155 }
156
AddPropertyHolder(CFX_CSSProperty eProperty,RetainPtr<CFX_CSSValue> pValue,bool bImportant)157 void CFX_CSSDeclaration::AddPropertyHolder(CFX_CSSProperty eProperty,
158 RetainPtr<CFX_CSSValue> pValue,
159 bool bImportant) {
160 auto pHolder = pdfium::MakeUnique<CFX_CSSPropertyHolder>();
161 pHolder->bImportant = bImportant;
162 pHolder->eProperty = eProperty;
163 pHolder->pValue = pValue;
164 properties_.push_back(std::move(pHolder));
165 }
166
AddProperty(const CFX_CSSData::Property * property,WideStringView value)167 void CFX_CSSDeclaration::AddProperty(const CFX_CSSData::Property* property,
168 WideStringView value) {
169 ASSERT(!value.IsEmpty());
170
171 const wchar_t* pszValue = value.unterminated_c_str();
172 int32_t iValueLen = value.GetLength();
173 bool bImportant = false;
174 if (iValueLen >= 10 && pszValue[iValueLen - 10] == '!' &&
175 FXSYS_wcsnicmp(L"important", pszValue + iValueLen - 9, 9) == 0) {
176 if ((iValueLen -= 10) == 0)
177 return;
178
179 bImportant = true;
180 }
181 const uint32_t dwType = property->dwType;
182 switch (dwType & 0x0F) {
183 case CFX_CSSVALUETYPE_Primitive: {
184 static constexpr CFX_CSSVALUETYPE kValueGuessOrder[] = {
185 CFX_CSSVALUETYPE_MaybeNumber,
186 CFX_CSSVALUETYPE_MaybeEnum,
187 CFX_CSSVALUETYPE_MaybeColor,
188 CFX_CSSVALUETYPE_MaybeString,
189 };
190 for (uint32_t guess : kValueGuessOrder) {
191 const uint32_t dwMatch = dwType & guess;
192 if (dwMatch == 0)
193 continue;
194
195 RetainPtr<CFX_CSSValue> pCSSValue;
196 switch (dwMatch) {
197 case CFX_CSSVALUETYPE_MaybeNumber:
198 pCSSValue = ParseNumber(pszValue, iValueLen);
199 break;
200 case CFX_CSSVALUETYPE_MaybeEnum:
201 pCSSValue = ParseEnum(pszValue, iValueLen);
202 break;
203 case CFX_CSSVALUETYPE_MaybeColor:
204 pCSSValue = ParseColor(pszValue, iValueLen);
205 break;
206 case CFX_CSSVALUETYPE_MaybeString:
207 pCSSValue = ParseString(pszValue, iValueLen);
208 break;
209 default:
210 break;
211 }
212 if (pCSSValue) {
213 AddPropertyHolder(property->eName, pCSSValue, bImportant);
214 return;
215 }
216
217 if ((dwType & ~guess) == CFX_CSSVALUETYPE_Primitive)
218 return;
219 }
220 break;
221 }
222 case CFX_CSSVALUETYPE_Shorthand: {
223 RetainPtr<CFX_CSSValue> pWidth;
224 switch (property->eName) {
225 case CFX_CSSProperty::Font:
226 ParseFontProperty(pszValue, iValueLen, bImportant);
227 return;
228 case CFX_CSSProperty::Border:
229 if (ParseBorderProperty(pszValue, iValueLen, pWidth)) {
230 AddPropertyHolder(CFX_CSSProperty::BorderLeftWidth, pWidth,
231 bImportant);
232 AddPropertyHolder(CFX_CSSProperty::BorderTopWidth, pWidth,
233 bImportant);
234 AddPropertyHolder(CFX_CSSProperty::BorderRightWidth, pWidth,
235 bImportant);
236 AddPropertyHolder(CFX_CSSProperty::BorderBottomWidth, pWidth,
237 bImportant);
238 return;
239 }
240 break;
241 case CFX_CSSProperty::BorderLeft:
242 if (ParseBorderProperty(pszValue, iValueLen, pWidth)) {
243 AddPropertyHolder(CFX_CSSProperty::BorderLeftWidth, pWidth,
244 bImportant);
245 return;
246 }
247 break;
248 case CFX_CSSProperty::BorderTop:
249 if (ParseBorderProperty(pszValue, iValueLen, pWidth)) {
250 AddPropertyHolder(CFX_CSSProperty::BorderTopWidth, pWidth,
251 bImportant);
252 return;
253 }
254 break;
255 case CFX_CSSProperty::BorderRight:
256 if (ParseBorderProperty(pszValue, iValueLen, pWidth)) {
257 AddPropertyHolder(CFX_CSSProperty::BorderRightWidth, pWidth,
258 bImportant);
259 return;
260 }
261 break;
262 case CFX_CSSProperty::BorderBottom:
263 if (ParseBorderProperty(pszValue, iValueLen, pWidth)) {
264 AddPropertyHolder(CFX_CSSProperty::BorderBottomWidth, pWidth,
265 bImportant);
266 return;
267 }
268 break;
269 default:
270 break;
271 }
272 } break;
273 case CFX_CSSVALUETYPE_List:
274 ParseValueListProperty(property, pszValue, iValueLen, bImportant);
275 return;
276 default:
277 NOTREACHED();
278 break;
279 }
280 }
281
AddProperty(const WideString & prop,const WideString & value)282 void CFX_CSSDeclaration::AddProperty(const WideString& prop,
283 const WideString& value) {
284 custom_properties_.push_back(
285 pdfium::MakeUnique<CFX_CSSCustomProperty>(prop, value));
286 }
287
ParseNumber(const wchar_t * pszValue,int32_t iValueLen)288 RetainPtr<CFX_CSSValue> CFX_CSSDeclaration::ParseNumber(const wchar_t* pszValue,
289 int32_t iValueLen) {
290 float fValue;
291 CFX_CSSNumberType eUnit;
292 if (!ParseCSSNumber(pszValue, iValueLen, &fValue, &eUnit))
293 return nullptr;
294 return pdfium::MakeRetain<CFX_CSSNumberValue>(eUnit, fValue);
295 }
296
ParseEnum(const wchar_t * pszValue,int32_t iValueLen)297 RetainPtr<CFX_CSSValue> CFX_CSSDeclaration::ParseEnum(const wchar_t* pszValue,
298 int32_t iValueLen) {
299 const CFX_CSSData::PropertyValue* pValue =
300 CFX_CSSData::GetPropertyValueByName(WideStringView(pszValue, iValueLen));
301 return pValue ? pdfium::MakeRetain<CFX_CSSEnumValue>(pValue->eName) : nullptr;
302 }
303
ParseColor(const wchar_t * pszValue,int32_t iValueLen)304 RetainPtr<CFX_CSSValue> CFX_CSSDeclaration::ParseColor(const wchar_t* pszValue,
305 int32_t iValueLen) {
306 FX_ARGB dwColor;
307 if (!ParseCSSColor(pszValue, iValueLen, &dwColor))
308 return nullptr;
309 return pdfium::MakeRetain<CFX_CSSColorValue>(dwColor);
310 }
311
ParseString(const wchar_t * pszValue,int32_t iValueLen)312 RetainPtr<CFX_CSSValue> CFX_CSSDeclaration::ParseString(const wchar_t* pszValue,
313 int32_t iValueLen) {
314 int32_t iOffset;
315 if (!ParseCSSString(pszValue, iValueLen, &iOffset, &iValueLen))
316 return nullptr;
317
318 if (iValueLen <= 0)
319 return nullptr;
320
321 return pdfium::MakeRetain<CFX_CSSStringValue>(
322 WideString(pszValue + iOffset, iValueLen));
323 }
324
ParseValueListProperty(const CFX_CSSData::Property * pProperty,const wchar_t * pszValue,int32_t iValueLen,bool bImportant)325 void CFX_CSSDeclaration::ParseValueListProperty(
326 const CFX_CSSData::Property* pProperty,
327 const wchar_t* pszValue,
328 int32_t iValueLen,
329 bool bImportant) {
330 wchar_t separator =
331 (pProperty->eName == CFX_CSSProperty::FontFamily) ? ',' : ' ';
332 CFX_CSSValueListParser parser(pszValue, iValueLen, separator);
333
334 const uint32_t dwType = pProperty->dwType;
335 CFX_CSSPrimitiveType eType;
336 std::vector<RetainPtr<CFX_CSSValue>> list;
337 while (parser.NextValue(&eType, &pszValue, &iValueLen)) {
338 switch (eType) {
339 case CFX_CSSPrimitiveType::Number:
340 if (dwType & CFX_CSSVALUETYPE_MaybeNumber) {
341 float fValue;
342 CFX_CSSNumberType eNumType;
343 if (ParseCSSNumber(pszValue, iValueLen, &fValue, &eNumType))
344 list.push_back(
345 pdfium::MakeRetain<CFX_CSSNumberValue>(eNumType, fValue));
346 }
347 break;
348 case CFX_CSSPrimitiveType::String:
349 if (dwType & CFX_CSSVALUETYPE_MaybeColor) {
350 FX_ARGB dwColor;
351 if (ParseCSSColor(pszValue, iValueLen, &dwColor)) {
352 list.push_back(pdfium::MakeRetain<CFX_CSSColorValue>(dwColor));
353 continue;
354 }
355 }
356 if (dwType & CFX_CSSVALUETYPE_MaybeEnum) {
357 const CFX_CSSData::PropertyValue* pValue =
358 CFX_CSSData::GetPropertyValueByName(
359 WideStringView(pszValue, iValueLen));
360 if (pValue) {
361 list.push_back(pdfium::MakeRetain<CFX_CSSEnumValue>(pValue->eName));
362 continue;
363 }
364 }
365 if (dwType & CFX_CSSVALUETYPE_MaybeString) {
366 list.push_back(pdfium::MakeRetain<CFX_CSSStringValue>(
367 WideString(pszValue, iValueLen)));
368 }
369 break;
370 case CFX_CSSPrimitiveType::RGB:
371 if (dwType & CFX_CSSVALUETYPE_MaybeColor) {
372 FX_ARGB dwColor;
373 if (ParseCSSColor(pszValue, iValueLen, &dwColor)) {
374 list.push_back(pdfium::MakeRetain<CFX_CSSColorValue>(dwColor));
375 }
376 }
377 break;
378 default:
379 break;
380 }
381 }
382 if (list.empty())
383 return;
384
385 switch (pProperty->eName) {
386 case CFX_CSSProperty::BorderWidth:
387 Add4ValuesProperty(list, bImportant, CFX_CSSProperty::BorderLeftWidth,
388 CFX_CSSProperty::BorderTopWidth,
389 CFX_CSSProperty::BorderRightWidth,
390 CFX_CSSProperty::BorderBottomWidth);
391 return;
392 case CFX_CSSProperty::Margin:
393 Add4ValuesProperty(list, bImportant, CFX_CSSProperty::MarginLeft,
394 CFX_CSSProperty::MarginTop,
395 CFX_CSSProperty::MarginRight,
396 CFX_CSSProperty::MarginBottom);
397 return;
398 case CFX_CSSProperty::Padding:
399 Add4ValuesProperty(list, bImportant, CFX_CSSProperty::PaddingLeft,
400 CFX_CSSProperty::PaddingTop,
401 CFX_CSSProperty::PaddingRight,
402 CFX_CSSProperty::PaddingBottom);
403 return;
404 default: {
405 auto pList = pdfium::MakeRetain<CFX_CSSValueList>(list);
406 AddPropertyHolder(pProperty->eName, pList, bImportant);
407 return;
408 }
409 }
410 }
411
Add4ValuesProperty(const std::vector<RetainPtr<CFX_CSSValue>> & list,bool bImportant,CFX_CSSProperty eLeft,CFX_CSSProperty eTop,CFX_CSSProperty eRight,CFX_CSSProperty eBottom)412 void CFX_CSSDeclaration::Add4ValuesProperty(
413 const std::vector<RetainPtr<CFX_CSSValue>>& list,
414 bool bImportant,
415 CFX_CSSProperty eLeft,
416 CFX_CSSProperty eTop,
417 CFX_CSSProperty eRight,
418 CFX_CSSProperty eBottom) {
419 switch (list.size()) {
420 case 1:
421 AddPropertyHolder(eLeft, list[0], bImportant);
422 AddPropertyHolder(eTop, list[0], bImportant);
423 AddPropertyHolder(eRight, list[0], bImportant);
424 AddPropertyHolder(eBottom, list[0], bImportant);
425 return;
426 case 2:
427 AddPropertyHolder(eLeft, list[1], bImportant);
428 AddPropertyHolder(eTop, list[0], bImportant);
429 AddPropertyHolder(eRight, list[1], bImportant);
430 AddPropertyHolder(eBottom, list[0], bImportant);
431 return;
432 case 3:
433 AddPropertyHolder(eLeft, list[1], bImportant);
434 AddPropertyHolder(eTop, list[0], bImportant);
435 AddPropertyHolder(eRight, list[1], bImportant);
436 AddPropertyHolder(eBottom, list[2], bImportant);
437 return;
438 case 4:
439 AddPropertyHolder(eLeft, list[3], bImportant);
440 AddPropertyHolder(eTop, list[0], bImportant);
441 AddPropertyHolder(eRight, list[1], bImportant);
442 AddPropertyHolder(eBottom, list[2], bImportant);
443 return;
444 default:
445 break;
446 }
447 }
448
ParseBorderProperty(const wchar_t * pszValue,int32_t iValueLen,RetainPtr<CFX_CSSValue> & pWidth) const449 bool CFX_CSSDeclaration::ParseBorderProperty(
450 const wchar_t* pszValue,
451 int32_t iValueLen,
452 RetainPtr<CFX_CSSValue>& pWidth) const {
453 pWidth.Reset(nullptr);
454
455 CFX_CSSValueListParser parser(pszValue, iValueLen, ' ');
456 CFX_CSSPrimitiveType eType;
457 while (parser.NextValue(&eType, &pszValue, &iValueLen)) {
458 switch (eType) {
459 case CFX_CSSPrimitiveType::Number: {
460 if (pWidth)
461 continue;
462
463 float fValue;
464 CFX_CSSNumberType eNumType;
465 if (ParseCSSNumber(pszValue, iValueLen, &fValue, &eNumType))
466 pWidth = pdfium::MakeRetain<CFX_CSSNumberValue>(eNumType, fValue);
467 break;
468 }
469 case CFX_CSSPrimitiveType::String: {
470 const CFX_CSSData::Color* pColorItem =
471 CFX_CSSData::GetColorByName(WideStringView(pszValue, iValueLen));
472 if (pColorItem)
473 continue;
474
475 const CFX_CSSData::PropertyValue* pValue =
476 CFX_CSSData::GetPropertyValueByName(
477 WideStringView(pszValue, iValueLen));
478 if (!pValue)
479 continue;
480
481 switch (pValue->eName) {
482 case CFX_CSSPropertyValue::Thin:
483 case CFX_CSSPropertyValue::Thick:
484 case CFX_CSSPropertyValue::Medium:
485 if (!pWidth)
486 pWidth = pdfium::MakeRetain<CFX_CSSEnumValue>(pValue->eName);
487 break;
488 default:
489 break;
490 }
491 break;
492 }
493 default:
494 break;
495 }
496 }
497 if (!pWidth)
498 pWidth =
499 pdfium::MakeRetain<CFX_CSSNumberValue>(CFX_CSSNumberType::Number, 0.0f);
500
501 return true;
502 }
503
ParseFontProperty(const wchar_t * pszValue,int32_t iValueLen,bool bImportant)504 void CFX_CSSDeclaration::ParseFontProperty(const wchar_t* pszValue,
505 int32_t iValueLen,
506 bool bImportant) {
507 CFX_CSSValueListParser parser(pszValue, iValueLen, '/');
508 RetainPtr<CFX_CSSValue> pStyle;
509 RetainPtr<CFX_CSSValue> pVariant;
510 RetainPtr<CFX_CSSValue> pWeight;
511 RetainPtr<CFX_CSSValue> pFontSize;
512 RetainPtr<CFX_CSSValue> pLineHeight;
513 std::vector<RetainPtr<CFX_CSSValue>> familyList;
514 CFX_CSSPrimitiveType eType;
515 while (parser.NextValue(&eType, &pszValue, &iValueLen)) {
516 switch (eType) {
517 case CFX_CSSPrimitiveType::String: {
518 const CFX_CSSData::PropertyValue* pValue =
519 CFX_CSSData::GetPropertyValueByName(
520 WideStringView(pszValue, iValueLen));
521 if (pValue) {
522 switch (pValue->eName) {
523 case CFX_CSSPropertyValue::XxSmall:
524 case CFX_CSSPropertyValue::XSmall:
525 case CFX_CSSPropertyValue::Small:
526 case CFX_CSSPropertyValue::Medium:
527 case CFX_CSSPropertyValue::Large:
528 case CFX_CSSPropertyValue::XLarge:
529 case CFX_CSSPropertyValue::XxLarge:
530 case CFX_CSSPropertyValue::Smaller:
531 case CFX_CSSPropertyValue::Larger:
532 if (!pFontSize)
533 pFontSize = pdfium::MakeRetain<CFX_CSSEnumValue>(pValue->eName);
534 continue;
535 case CFX_CSSPropertyValue::Bold:
536 case CFX_CSSPropertyValue::Bolder:
537 case CFX_CSSPropertyValue::Lighter:
538 if (!pWeight)
539 pWeight = pdfium::MakeRetain<CFX_CSSEnumValue>(pValue->eName);
540 continue;
541 case CFX_CSSPropertyValue::Italic:
542 case CFX_CSSPropertyValue::Oblique:
543 if (!pStyle)
544 pStyle = pdfium::MakeRetain<CFX_CSSEnumValue>(pValue->eName);
545 continue;
546 case CFX_CSSPropertyValue::SmallCaps:
547 if (!pVariant)
548 pVariant = pdfium::MakeRetain<CFX_CSSEnumValue>(pValue->eName);
549 continue;
550 case CFX_CSSPropertyValue::Normal:
551 if (!pStyle)
552 pStyle = pdfium::MakeRetain<CFX_CSSEnumValue>(pValue->eName);
553 else if (!pVariant)
554 pVariant = pdfium::MakeRetain<CFX_CSSEnumValue>(pValue->eName);
555 else if (!pWeight)
556 pWeight = pdfium::MakeRetain<CFX_CSSEnumValue>(pValue->eName);
557 else if (!pFontSize)
558 pFontSize = pdfium::MakeRetain<CFX_CSSEnumValue>(pValue->eName);
559 else if (!pLineHeight)
560 pLineHeight =
561 pdfium::MakeRetain<CFX_CSSEnumValue>(pValue->eName);
562 continue;
563 default:
564 break;
565 }
566 }
567 if (pFontSize) {
568 familyList.push_back(pdfium::MakeRetain<CFX_CSSStringValue>(
569 WideString(pszValue, iValueLen)));
570 }
571 parser.UseCommaSeparator();
572 break;
573 }
574 case CFX_CSSPrimitiveType::Number: {
575 float fValue;
576 CFX_CSSNumberType eNumType;
577 if (!ParseCSSNumber(pszValue, iValueLen, &fValue, &eNumType))
578 break;
579 if (eType == CFX_CSSPrimitiveType::Number) {
580 switch ((int32_t)fValue) {
581 case 100:
582 case 200:
583 case 300:
584 case 400:
585 case 500:
586 case 600:
587 case 700:
588 case 800:
589 case 900:
590 if (!pWeight)
591 pWeight = pdfium::MakeRetain<CFX_CSSNumberValue>(
592 CFX_CSSNumberType::Number, fValue);
593 continue;
594 }
595 }
596 if (!pFontSize)
597 pFontSize = pdfium::MakeRetain<CFX_CSSNumberValue>(eNumType, fValue);
598 else if (!pLineHeight)
599 pLineHeight =
600 pdfium::MakeRetain<CFX_CSSNumberValue>(eNumType, fValue);
601 break;
602 }
603 default:
604 break;
605 }
606 }
607
608 if (!pStyle) {
609 pStyle = pdfium::MakeRetain<CFX_CSSEnumValue>(CFX_CSSPropertyValue::Normal);
610 }
611 if (!pVariant) {
612 pVariant =
613 pdfium::MakeRetain<CFX_CSSEnumValue>(CFX_CSSPropertyValue::Normal);
614 }
615 if (!pWeight) {
616 pWeight =
617 pdfium::MakeRetain<CFX_CSSEnumValue>(CFX_CSSPropertyValue::Normal);
618 }
619 if (!pFontSize) {
620 pFontSize =
621 pdfium::MakeRetain<CFX_CSSEnumValue>(CFX_CSSPropertyValue::Medium);
622 }
623 if (!pLineHeight) {
624 pLineHeight =
625 pdfium::MakeRetain<CFX_CSSEnumValue>(CFX_CSSPropertyValue::Normal);
626 }
627
628 AddPropertyHolder(CFX_CSSProperty::FontStyle, pStyle, bImportant);
629 AddPropertyHolder(CFX_CSSProperty::FontVariant, pVariant, bImportant);
630 AddPropertyHolder(CFX_CSSProperty::FontWeight, pWeight, bImportant);
631 AddPropertyHolder(CFX_CSSProperty::FontSize, pFontSize, bImportant);
632 AddPropertyHolder(CFX_CSSProperty::LineHeight, pLineHeight, bImportant);
633 if (!familyList.empty()) {
634 auto pList = pdfium::MakeRetain<CFX_CSSValueList>(familyList);
635 AddPropertyHolder(CFX_CSSProperty::FontFamily, pList, bImportant);
636 }
637 }
638
PropertyCountForTesting() const639 size_t CFX_CSSDeclaration::PropertyCountForTesting() const {
640 return properties_.size();
641 }
642