7#include "core/fxcrt/css/cfx_cssdeclaration.h"
13#include "core/fxcrt/css/cfx_csscolorvalue.h"
14#include "core/fxcrt/css/cfx_csscustomproperty.h"
15#include "core/fxcrt/css/cfx_cssenumvalue.h"
16#include "core/fxcrt/css/cfx_cssnumbervalue.h"
17#include "core/fxcrt/css/cfx_csspropertyholder.h"
18#include "core/fxcrt/css/cfx_cssstringvalue.h"
19#include "core/fxcrt/css/cfx_cssvaluelist.h"
20#include "core/fxcrt/css/cfx_cssvaluelistparser.h"
21#include "core/fxcrt/fx_extension.h"
22#include "core/fxcrt/fx_system.h"
23#include "third_party/base/check.h"
24#include "third_party/base/check_op.h"
25#include "third_party/base/notreached.h"
29uint8_t Hex2Dec(uint8_t hexHigh, uint8_t hexLow) {
33bool ParseCSSNumber(
const wchar_t* pszValue,
36 CFX_CSSNumberValue::
Unit* pOutUnit) {
38 DCHECK_NE(nValueLen, 0);
41 *pValue = FXSYS_wcstof(pszValue, nValueLen, &nUsedLen);
42 if (nUsedLen == 0 || !isfinite(*pValue))
45 nValueLen -= nUsedLen;
48 if (nValueLen >= 1 && *pszValue ==
'%') {
50 }
else if (nValueLen == 2) {
67 DCHECK_NE(nValueLen, 0);
72 wchar_t first = pszValue[0];
73 wchar_t last = pszValue[nValueLen - 1];
74 if ((first ==
'\"' && last ==
'\"') || (first ==
'\'' && last ==
'\'')) {
86 DCHECK_NE(nValueLen, 0);
89 if (*pszValue ==
'#') {
92 uint8_t red = Hex2Dec((uint8_t)pszValue[1], (uint8_t)pszValue[1]);
93 uint8_t green = Hex2Dec((uint8_t)pszValue[2], (uint8_t)pszValue[2]);
94 uint8_t blue = Hex2Dec((uint8_t)pszValue[3], (uint8_t)pszValue[3]);
99 uint8_t red = Hex2Dec((uint8_t)pszValue[1], (uint8_t)pszValue[2]);
100 uint8_t green = Hex2Dec((uint8_t)pszValue[3], (uint8_t)pszValue[4]);
101 uint8_t blue = Hex2Dec((uint8_t)pszValue[5], (uint8_t)pszValue[6]);
110 if (nValueLen >= 10) {
111 if (pszValue[nValueLen - 1] !=
')' || FXSYS_wcsnicmp(L"rgb(", pszValue, 4))
114 uint8_t rgb[3] = {0};
118 for (int32_t i = 0; i < 3; ++i) {
119 if (!list.NextValue(&eType, &pszValue, &nValueLen))
123 CFX_CSSNumberValue::
Unit eNumType;
124 if (!ParseCSSNumber(pszValue, nValueLen, &fValue, &eNumType))
150 bool* bImportant)
const {
151 for (
const auto& p : properties_) {
152 if (p->eProperty == eProperty) {
153 *bImportant = p->bImportant;
164 pHolder->bImportant = bImportant;
165 pHolder->eProperty = eProperty;
166 pHolder->pValue = pValue;
167 properties_.push_back(std::move(pHolder));
171 WideStringView value) {
172 DCHECK(!value.IsEmpty());
174 const wchar_t* pszValue = value.unterminated_c_str();
175 size_t nValueLen = value.GetLength();
176 bool bImportant =
false;
177 if (nValueLen >= 10 && pszValue[nValueLen - 10] ==
'!' &&
178 FXSYS_wcsnicmp(L"important", pszValue + nValueLen - 9, 9) == 0) {
185 const CFX_CSSValueTypeMask dwType = property->dwTypes;
186 switch (dwType & 0x0F) {
195 const CFX_CSSValueTypeMask dwMatch = dwType & guess;
201 case CFX_CSSVALUETYPE_MaybeNumber:
202 pCSSValue = ParseNumber(pszValue, nValueLen);
204 case CFX_CSSVALUETYPE_MaybeEnum:
205 pCSSValue = ParseEnum(pszValue, nValueLen);
207 case CFX_CSSVALUETYPE_MaybeColor:
208 pCSSValue = ParseColor(pszValue, nValueLen);
210 case CFX_CSSVALUETYPE_MaybeString:
211 pCSSValue = ParseString(pszValue, nValueLen);
217 AddPropertyHolder(property
->eName, pCSSValue, bImportant);
229 case CFX_CSSProperty::Font:
230 ParseFontProperty(pszValue, nValueLen, bImportant);
233 if (ParseBorderProperty(pszValue, nValueLen, pWidth)) {
246 if (ParseBorderProperty(pszValue, nValueLen, pWidth)) {
253 if (ParseBorderProperty(pszValue, nValueLen, pWidth)) {
260 if (ParseBorderProperty(pszValue, nValueLen, pWidth)) {
267 if (ParseBorderProperty(pszValue, nValueLen, pWidth)) {
277 case CFX_CSSVALUETYPE_List:
278 ParseValueListProperty(property, pszValue, nValueLen, bImportant);
281 NOTREACHED_NORETURN();
286 const WideString& value) {
287 custom_properties_.push_back(
288 std::make_unique<CFX_CSSCustomProperty>(prop, value));
294 CFX_CSSNumberValue::
Unit eUnit;
295 if (!ParseCSSNumber(pszValue, nValueLen, &fValue, &eUnit))
297 return pdfium::MakeRetain<CFX_CSSNumberValue>(eUnit, fValue);
304 return pValue ? pdfium::MakeRetain<CFX_CSSEnumValue>(pValue
->eName) :
nullptr;
310 if (!ParseCSSColor(pszValue, nValueLen, &dwColor))
312 return pdfium::MakeRetain<CFX_CSSColorValue>(dwColor);
318 if (!ParseCSSString(pszValue, nValueLen, &iOffset, &nValueLen))
324 return pdfium::MakeRetain<CFX_CSSStringValue>(
325 WideString(pszValue + iOffset, nValueLen));
330 const wchar_t* pszValue,
337 const CFX_CSSValueTypeMask dwType = pProperty->dwTypes;
339 std::vector<RetainPtr<CFX_CSSValue>> list;
340 while (parser.NextValue(&eType, &pszValue, &nValueLen)) {
345 CFX_CSSNumberValue::
Unit eNumType;
346 if (ParseCSSNumber(pszValue, nValueLen, &fValue, &eNumType))
348 pdfium::MakeRetain<CFX_CSSNumberValue>(eNumType, fValue));
354 if (ParseCSSColor(pszValue, nValueLen, &dwColor)) {
355 list.push_back(pdfium::MakeRetain<CFX_CSSColorValue>(dwColor));
362 WideStringView(pszValue, nValueLen));
364 list.push_back(pdfium::MakeRetain<CFX_CSSEnumValue>(pValue
->eName));
369 list.push_back(pdfium::MakeRetain<CFX_CSSStringValue>(
370 WideString(pszValue, nValueLen)));
376 if (ParseCSSColor(pszValue, nValueLen, &dwColor)) {
377 list.push_back(pdfium::MakeRetain<CFX_CSSColorValue>(dwColor));
389 case CFX_CSSProperty::BorderWidth:
390 Add4ValuesProperty(list, bImportant, CFX_CSSProperty::BorderLeftWidth,
391 CFX_CSSProperty::BorderTopWidth,
392 CFX_CSSProperty::BorderRightWidth,
393 CFX_CSSProperty::BorderBottomWidth);
395 case CFX_CSSProperty::Margin:
396 Add4ValuesProperty(list, bImportant, CFX_CSSProperty::MarginLeft,
397 CFX_CSSProperty::MarginTop,
398 CFX_CSSProperty::MarginRight,
399 CFX_CSSProperty::MarginBottom);
401 case CFX_CSSProperty::Padding:
402 Add4ValuesProperty(list, bImportant, CFX_CSSProperty::PaddingLeft,
403 CFX_CSSProperty::PaddingTop,
404 CFX_CSSProperty::PaddingRight,
405 CFX_CSSProperty::PaddingBottom);
408 auto value_list = pdfium::MakeRetain<CFX_CSSValueList>(
std::move(list));
409 AddPropertyHolder(pProperty
->eName, value_list, bImportant);
416 const std::vector<RetainPtr<CFX_CSSValue>>& list,
422 switch (list.size()) {
424 AddPropertyHolder(eLeft, list[0], bImportant);
425 AddPropertyHolder(eTop, list[0], bImportant);
426 AddPropertyHolder(eRight, list[0], bImportant);
427 AddPropertyHolder(eBottom, list[0], bImportant);
430 AddPropertyHolder(eLeft, list[1], bImportant);
431 AddPropertyHolder(eTop, list[0], bImportant);
432 AddPropertyHolder(eRight, list[1], bImportant);
433 AddPropertyHolder(eBottom, list[0], bImportant);
436 AddPropertyHolder(eLeft, list[1], bImportant);
437 AddPropertyHolder(eTop, list[0], bImportant);
438 AddPropertyHolder(eRight, list[1], bImportant);
439 AddPropertyHolder(eBottom, list[2], bImportant);
442 AddPropertyHolder(eLeft, list[3], bImportant);
443 AddPropertyHolder(eTop, list[0], bImportant);
444 AddPropertyHolder(eRight, list[1], bImportant);
445 AddPropertyHolder(eBottom, list[2], bImportant);
453 const wchar_t* pszValue,
456 pWidth.Reset(
nullptr);
460 while (parser.NextValue(&eType, &pszValue, &nValueLen)) {
467 CFX_CSSNumberValue::
Unit eNumType;
468 if (ParseCSSNumber(pszValue, nValueLen, &fValue, &eNumType))
469 pWidth = pdfium::MakeRetain<CFX_CSSNumberValue>(eNumType, fValue);
480 WideStringView(pszValue, nValueLen));
489 pWidth = pdfium::MakeRetain<CFX_CSSEnumValue>(pValue
->eName);
501 pWidth = pdfium::MakeRetain<CFX_CSSNumberValue>(
516 std::vector<RetainPtr<CFX_CSSValue>> family_list;
518 while (parser.NextValue(&eType, &pszValue, &nValueLen)) {
523 WideStringView(pszValue, nValueLen));
536 pFontSize = pdfium::MakeRetain<CFX_CSSEnumValue>(pValue
->eName);
542 pWeight = pdfium::MakeRetain<CFX_CSSEnumValue>(pValue
->eName);
547 pStyle = pdfium::MakeRetain<CFX_CSSEnumValue>(pValue
->eName);
551 pVariant = pdfium::MakeRetain<CFX_CSSEnumValue>(pValue
->eName);
555 pStyle = pdfium::MakeRetain<CFX_CSSEnumValue>(pValue
->eName);
557 pVariant = pdfium::MakeRetain<CFX_CSSEnumValue>(pValue
->eName);
559 pWeight = pdfium::MakeRetain<CFX_CSSEnumValue>(pValue
->eName);
561 pFontSize = pdfium::MakeRetain<CFX_CSSEnumValue>(pValue
->eName);
562 else if (!pLineHeight)
564 pdfium::MakeRetain<CFX_CSSEnumValue>(pValue
->eName);
571 family_list.push_back(pdfium::MakeRetain<CFX_CSSStringValue>(
572 WideString(pszValue, nValueLen)));
579 CFX_CSSNumberValue::
Unit eNumType;
580 if (!ParseCSSNumber(pszValue, nValueLen, &fValue, &eNumType))
583 switch (
static_cast<int32_t>(fValue)) {
594 pWeight = pdfium::MakeRetain<CFX_CSSNumberValue>(
601 pFontSize = pdfium::MakeRetain<CFX_CSSNumberValue>(eNumType, fValue);
602 else if (!pLineHeight)
604 pdfium::MakeRetain<CFX_CSSNumberValue>(eNumType, fValue);
636 AddPropertyHolder(
CFX_CSSProperty::LineHeight, pLineHeight, bImportant);
637 if (!family_list.empty()) {
639 pdfium::MakeRetain<CFX_CSSValueList>(
std::move(family_list));
640 AddPropertyHolder(
CFX_CSSProperty::FontFamily, value_list, bImportant);
645 return properties_.size();
@ CFX_CSSVALUETYPE_Shorthand
@ CFX_CSSVALUETYPE_Primitive
@ CFX_CSSVALUETYPE_MaybeEnum
@ CFX_CSSVALUETYPE_MaybeString
@ CFX_CSSVALUETYPE_MaybeColor
@ CFX_CSSVALUETYPE_MaybeNumber
static const Color * GetColorByName(WideStringView wsName)
static const LengthUnit * GetLengthUnitByName(WideStringView wsName)
static const PropertyValue * GetPropertyValueByName(WideStringView wsName)
void AddProperty(const CFX_CSSData::Property *property, WideStringView value)
void AddProperty(const WideString &prop, const WideString &value)
size_t PropertyCountForTesting() const
RetainPtr< CFX_CSSValue > GetProperty(CFX_CSSProperty eProperty, bool *bImportant) const
constexpr FX_ARGB ArgbEncode(uint32_t a, uint32_t r, uint32_t g, uint32_t b)
int FXSYS_HexCharToInt(char c)
int FXSYS_roundf(float f)
CFX_CSSNumberValue::Unit type
CFX_CSSPropertyValue eName