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