cfde_cssdeclaration.cpp revision 33357cad1fd1321a2b38d2963e2585f27ce980a2
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 20namespace { 21 22uint8_t Hex2Dec(uint8_t hexHigh, uint8_t hexLow) { 23 return (FXSYS_toHexDigit(hexHigh) << 4) + FXSYS_toHexDigit(hexLow); 24} 25 26bool 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 53bool 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. 71bool 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 132CFDE_CSSDeclaration::CFDE_CSSDeclaration() {} 133 134CFDE_CSSDeclaration::~CFDE_CSSDeclaration() {} 135 136CFX_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 148void 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 158void 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 273void 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 279CFX_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 289CFX_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 298CFX_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 307CFX_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 321void 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 409void 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 446bool 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 500void 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 637size_t CFDE_CSSDeclaration::PropertyCountForTesting() const { 638 return properties_.size(); 639} 640