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_cssstyleselector.h" 8 9 #include <algorithm> 10 #include <utility> 11 12 #include "third_party/base/ptr_util.h" 13 #include "xfa/fde/css/cfde_csscolorvalue.h" 14 #include "xfa/fde/css/cfde_csscomputedstyle.h" 15 #include "xfa/fde/css/cfde_csscustomproperty.h" 16 #include "xfa/fde/css/cfde_cssdeclaration.h" 17 #include "xfa/fde/css/cfde_cssenumvalue.h" 18 #include "xfa/fde/css/cfde_csspropertyholder.h" 19 #include "xfa/fde/css/cfde_cssselector.h" 20 #include "xfa/fde/css/cfde_cssstylesheet.h" 21 #include "xfa/fde/css/cfde_csssyntaxparser.h" 22 #include "xfa/fde/css/cfde_cssvaluelist.h" 23 #include "xfa/fxfa/app/cxfa_csstagprovider.h" 24 25 CFDE_CSSStyleSelector::CFDE_CSSStyleSelector(CFGAS_FontMgr* pFontMgr) 26 : m_pFontMgr(pFontMgr), m_fDefFontSize(12.0f) {} 27 28 CFDE_CSSStyleSelector::~CFDE_CSSStyleSelector() {} 29 30 void CFDE_CSSStyleSelector::SetDefFontSize(FX_FLOAT fFontSize) { 31 ASSERT(fFontSize > 0); 32 m_fDefFontSize = fFontSize; 33 } 34 35 CFX_RetainPtr<CFDE_CSSComputedStyle> CFDE_CSSStyleSelector::CreateComputedStyle( 36 CFDE_CSSComputedStyle* pParentStyle) { 37 auto pStyle = pdfium::MakeRetain<CFDE_CSSComputedStyle>(); 38 if (pParentStyle) 39 pStyle->m_InheritedData = pParentStyle->m_InheritedData; 40 return pStyle; 41 } 42 43 void CFDE_CSSStyleSelector::SetUAStyleSheet( 44 std::unique_ptr<CFDE_CSSStyleSheet> pSheet) { 45 m_UAStyles = std::move(pSheet); 46 } 47 48 void CFDE_CSSStyleSelector::UpdateStyleIndex() { 49 m_UARules.Clear(); 50 m_UARules.AddRulesFrom(m_UAStyles.get(), m_pFontMgr); 51 } 52 53 std::vector<const CFDE_CSSDeclaration*> 54 CFDE_CSSStyleSelector::MatchDeclarations(const CFX_WideString& tagname) { 55 std::vector<const CFDE_CSSDeclaration*> matchedDecls; 56 if (m_UARules.CountSelectors() == 0 || tagname.IsEmpty()) 57 return matchedDecls; 58 59 auto rules = m_UARules.GetTagRuleData(tagname); 60 if (!rules) 61 return matchedDecls; 62 63 for (const auto& d : *rules) { 64 if (MatchSelector(tagname, d->pSelector)) 65 matchedDecls.push_back(d->pDeclaration); 66 } 67 return matchedDecls; 68 } 69 70 bool CFDE_CSSStyleSelector::MatchSelector(const CFX_WideString& tagname, 71 CFDE_CSSSelector* pSel) { 72 // TODO(dsinclair): The code only supports a single level of selector at this 73 // point. None of the code using selectors required the complexity so lets 74 // just say we don't support them to simplify the code for now. 75 if (!pSel || pSel->GetNextSelector() || 76 pSel->GetType() == FDE_CSSSelectorType::Descendant) { 77 return false; 78 } 79 return pSel->GetNameHash() == FX_HashCode_GetW(tagname.c_str(), true); 80 } 81 82 void CFDE_CSSStyleSelector::ComputeStyle( 83 const std::vector<const CFDE_CSSDeclaration*>& declArray, 84 const CFX_WideString& styleString, 85 const CFX_WideString& alignString, 86 CFDE_CSSComputedStyle* pDest) { 87 std::unique_ptr<CFDE_CSSDeclaration> pDecl; 88 if (!styleString.IsEmpty() || !alignString.IsEmpty()) { 89 pDecl = pdfium::MakeUnique<CFDE_CSSDeclaration>(); 90 91 if (!styleString.IsEmpty()) 92 AppendInlineStyle(pDecl.get(), styleString); 93 if (!alignString.IsEmpty()) { 94 pDecl->AddProperty(FDE_GetCSSPropertyByEnum(FDE_CSSProperty::TextAlign), 95 alignString.AsStringC()); 96 } 97 } 98 ApplyDeclarations(declArray, pDecl.get(), pDest); 99 } 100 101 void CFDE_CSSStyleSelector::ApplyDeclarations( 102 const std::vector<const CFDE_CSSDeclaration*>& declArray, 103 const CFDE_CSSDeclaration* extraDecl, 104 CFDE_CSSComputedStyle* pComputedStyle) { 105 std::vector<const CFDE_CSSPropertyHolder*> importants; 106 std::vector<const CFDE_CSSPropertyHolder*> normals; 107 std::vector<const CFDE_CSSCustomProperty*> customs; 108 109 for (auto& decl : declArray) 110 ExtractValues(decl, &importants, &normals, &customs); 111 112 if (extraDecl) 113 ExtractValues(extraDecl, &importants, &normals, &customs); 114 115 for (auto& prop : normals) 116 ApplyProperty(prop->eProperty, prop->pValue, pComputedStyle); 117 118 for (auto& prop : customs) 119 pComputedStyle->AddCustomStyle(*prop); 120 121 for (auto& prop : importants) 122 ApplyProperty(prop->eProperty, prop->pValue, pComputedStyle); 123 } 124 125 void CFDE_CSSStyleSelector::ExtractValues( 126 const CFDE_CSSDeclaration* decl, 127 std::vector<const CFDE_CSSPropertyHolder*>* importants, 128 std::vector<const CFDE_CSSPropertyHolder*>* normals, 129 std::vector<const CFDE_CSSCustomProperty*>* custom) { 130 for (const auto& holder : *decl) { 131 if (holder->bImportant) 132 importants->push_back(holder.get()); 133 else 134 normals->push_back(holder.get()); 135 } 136 for (auto it = decl->custom_begin(); it != decl->custom_end(); it++) 137 custom->push_back(it->get()); 138 } 139 140 void CFDE_CSSStyleSelector::AppendInlineStyle(CFDE_CSSDeclaration* pDecl, 141 const CFX_WideString& style) { 142 ASSERT(pDecl && !style.IsEmpty()); 143 144 auto pSyntax = pdfium::MakeUnique<CFDE_CSSSyntaxParser>(); 145 if (!pSyntax->Init(style.c_str(), style.GetLength(), 32, true)) 146 return; 147 148 int32_t iLen2 = 0; 149 const FDE_CSSPropertyTable* table = nullptr; 150 CFX_WideString wsName; 151 while (1) { 152 FDE_CSSSyntaxStatus eStatus = pSyntax->DoSyntaxParse(); 153 if (eStatus == FDE_CSSSyntaxStatus::PropertyName) { 154 CFX_WideStringC strValue = pSyntax->GetCurrentString(); 155 table = FDE_GetCSSPropertyByName(strValue); 156 if (!table) 157 wsName = CFX_WideString(strValue); 158 } else if (eStatus == FDE_CSSSyntaxStatus::PropertyValue) { 159 if (table || iLen2 > 0) { 160 CFX_WideStringC strValue = pSyntax->GetCurrentString(); 161 if (!strValue.IsEmpty()) { 162 if (table) 163 pDecl->AddProperty(table, strValue); 164 else if (iLen2 > 0) 165 pDecl->AddProperty(wsName, CFX_WideString(strValue)); 166 } 167 } 168 } else { 169 break; 170 } 171 } 172 } 173 174 void CFDE_CSSStyleSelector::ApplyProperty( 175 FDE_CSSProperty eProperty, 176 const CFX_RetainPtr<CFDE_CSSValue>& pValue, 177 CFDE_CSSComputedStyle* pComputedStyle) { 178 if (pValue->GetType() != FDE_CSSPrimitiveType::List) { 179 FDE_CSSPrimitiveType eType = pValue->GetType(); 180 switch (eProperty) { 181 case FDE_CSSProperty::Display: 182 if (eType == FDE_CSSPrimitiveType::Enum) { 183 pComputedStyle->m_NonInheritedData.m_eDisplay = 184 ToDisplay(pValue.As<CFDE_CSSEnumValue>()->Value()); 185 } 186 break; 187 case FDE_CSSProperty::FontSize: { 188 FX_FLOAT& fFontSize = pComputedStyle->m_InheritedData.m_fFontSize; 189 if (eType == FDE_CSSPrimitiveType::Number) { 190 fFontSize = pValue.As<CFDE_CSSNumberValue>()->Apply(fFontSize); 191 } else if (eType == FDE_CSSPrimitiveType::Enum) { 192 fFontSize = 193 ToFontSize(pValue.As<CFDE_CSSEnumValue>()->Value(), fFontSize); 194 } 195 } break; 196 case FDE_CSSProperty::LineHeight: 197 if (eType == FDE_CSSPrimitiveType::Number) { 198 CFX_RetainPtr<CFDE_CSSNumberValue> v = 199 pValue.As<CFDE_CSSNumberValue>(); 200 if (v->Kind() == FDE_CSSNumberType::Number) { 201 pComputedStyle->m_InheritedData.m_fLineHeight = 202 v->Value() * pComputedStyle->m_InheritedData.m_fFontSize; 203 } else { 204 pComputedStyle->m_InheritedData.m_fLineHeight = 205 v->Apply(pComputedStyle->m_InheritedData.m_fFontSize); 206 } 207 } 208 break; 209 case FDE_CSSProperty::TextAlign: 210 if (eType == FDE_CSSPrimitiveType::Enum) { 211 pComputedStyle->m_InheritedData.m_eTextAlign = 212 ToTextAlign(pValue.As<CFDE_CSSEnumValue>()->Value()); 213 } 214 break; 215 case FDE_CSSProperty::TextIndent: 216 SetLengthWithPercent(pComputedStyle->m_InheritedData.m_TextIndent, 217 eType, pValue, 218 pComputedStyle->m_InheritedData.m_fFontSize); 219 break; 220 case FDE_CSSProperty::FontWeight: 221 if (eType == FDE_CSSPrimitiveType::Enum) { 222 pComputedStyle->m_InheritedData.m_wFontWeight = 223 ToFontWeight(pValue.As<CFDE_CSSEnumValue>()->Value()); 224 } else if (eType == FDE_CSSPrimitiveType::Number) { 225 int32_t iValue = 226 (int32_t)pValue.As<CFDE_CSSNumberValue>()->Value() / 100; 227 if (iValue >= 1 && iValue <= 9) { 228 pComputedStyle->m_InheritedData.m_wFontWeight = iValue * 100; 229 } 230 } 231 break; 232 case FDE_CSSProperty::FontStyle: 233 if (eType == FDE_CSSPrimitiveType::Enum) { 234 pComputedStyle->m_InheritedData.m_eFontStyle = 235 ToFontStyle(pValue.As<CFDE_CSSEnumValue>()->Value()); 236 } 237 break; 238 case FDE_CSSProperty::Color: 239 if (eType == FDE_CSSPrimitiveType::RGB) { 240 pComputedStyle->m_InheritedData.m_dwFontColor = 241 pValue.As<CFDE_CSSColorValue>()->Value(); 242 } 243 break; 244 case FDE_CSSProperty::MarginLeft: 245 if (SetLengthWithPercent( 246 pComputedStyle->m_NonInheritedData.m_MarginWidth.left, eType, 247 pValue, pComputedStyle->m_InheritedData.m_fFontSize)) { 248 pComputedStyle->m_NonInheritedData.m_bHasMargin = true; 249 } 250 break; 251 case FDE_CSSProperty::MarginTop: 252 if (SetLengthWithPercent( 253 pComputedStyle->m_NonInheritedData.m_MarginWidth.top, eType, 254 pValue, pComputedStyle->m_InheritedData.m_fFontSize)) { 255 pComputedStyle->m_NonInheritedData.m_bHasMargin = true; 256 } 257 break; 258 case FDE_CSSProperty::MarginRight: 259 if (SetLengthWithPercent( 260 pComputedStyle->m_NonInheritedData.m_MarginWidth.right, eType, 261 pValue, pComputedStyle->m_InheritedData.m_fFontSize)) { 262 pComputedStyle->m_NonInheritedData.m_bHasMargin = true; 263 } 264 break; 265 case FDE_CSSProperty::MarginBottom: 266 if (SetLengthWithPercent( 267 pComputedStyle->m_NonInheritedData.m_MarginWidth.bottom, eType, 268 pValue, pComputedStyle->m_InheritedData.m_fFontSize)) { 269 pComputedStyle->m_NonInheritedData.m_bHasMargin = true; 270 } 271 break; 272 case FDE_CSSProperty::PaddingLeft: 273 if (SetLengthWithPercent( 274 pComputedStyle->m_NonInheritedData.m_PaddingWidth.left, eType, 275 pValue, pComputedStyle->m_InheritedData.m_fFontSize)) { 276 pComputedStyle->m_NonInheritedData.m_bHasPadding = true; 277 } 278 break; 279 case FDE_CSSProperty::PaddingTop: 280 if (SetLengthWithPercent( 281 pComputedStyle->m_NonInheritedData.m_PaddingWidth.top, eType, 282 pValue, pComputedStyle->m_InheritedData.m_fFontSize)) { 283 pComputedStyle->m_NonInheritedData.m_bHasPadding = true; 284 } 285 break; 286 case FDE_CSSProperty::PaddingRight: 287 if (SetLengthWithPercent( 288 pComputedStyle->m_NonInheritedData.m_PaddingWidth.right, eType, 289 pValue, pComputedStyle->m_InheritedData.m_fFontSize)) { 290 pComputedStyle->m_NonInheritedData.m_bHasPadding = true; 291 } 292 break; 293 case FDE_CSSProperty::PaddingBottom: 294 if (SetLengthWithPercent( 295 pComputedStyle->m_NonInheritedData.m_PaddingWidth.bottom, eType, 296 pValue, pComputedStyle->m_InheritedData.m_fFontSize)) { 297 pComputedStyle->m_NonInheritedData.m_bHasPadding = true; 298 } 299 break; 300 case FDE_CSSProperty::BorderLeftWidth: 301 if (SetLengthWithPercent( 302 pComputedStyle->m_NonInheritedData.m_BorderWidth.left, eType, 303 pValue, pComputedStyle->m_InheritedData.m_fFontSize)) { 304 pComputedStyle->m_NonInheritedData.m_bHasBorder = true; 305 } 306 break; 307 case FDE_CSSProperty::BorderTopWidth: 308 if (SetLengthWithPercent( 309 pComputedStyle->m_NonInheritedData.m_BorderWidth.top, eType, 310 pValue, pComputedStyle->m_InheritedData.m_fFontSize)) { 311 pComputedStyle->m_NonInheritedData.m_bHasBorder = true; 312 } 313 break; 314 case FDE_CSSProperty::BorderRightWidth: 315 if (SetLengthWithPercent( 316 pComputedStyle->m_NonInheritedData.m_BorderWidth.right, eType, 317 pValue, pComputedStyle->m_InheritedData.m_fFontSize)) { 318 pComputedStyle->m_NonInheritedData.m_bHasBorder = true; 319 } 320 break; 321 case FDE_CSSProperty::BorderBottomWidth: 322 if (SetLengthWithPercent( 323 pComputedStyle->m_NonInheritedData.m_BorderWidth.bottom, eType, 324 pValue, pComputedStyle->m_InheritedData.m_fFontSize)) { 325 pComputedStyle->m_NonInheritedData.m_bHasBorder = true; 326 } 327 break; 328 case FDE_CSSProperty::VerticalAlign: 329 if (eType == FDE_CSSPrimitiveType::Enum) { 330 pComputedStyle->m_NonInheritedData.m_eVerticalAlign = 331 ToVerticalAlign(pValue.As<CFDE_CSSEnumValue>()->Value()); 332 } else if (eType == FDE_CSSPrimitiveType::Number) { 333 pComputedStyle->m_NonInheritedData.m_eVerticalAlign = 334 FDE_CSSVerticalAlign::Number; 335 pComputedStyle->m_NonInheritedData.m_fVerticalAlign = 336 pValue.As<CFDE_CSSNumberValue>()->Apply( 337 pComputedStyle->m_InheritedData.m_fFontSize); 338 } 339 break; 340 case FDE_CSSProperty::FontVariant: 341 if (eType == FDE_CSSPrimitiveType::Enum) { 342 pComputedStyle->m_InheritedData.m_eFontVariant = 343 ToFontVariant(pValue.As<CFDE_CSSEnumValue>()->Value()); 344 } 345 break; 346 case FDE_CSSProperty::LetterSpacing: 347 if (eType == FDE_CSSPrimitiveType::Enum) { 348 pComputedStyle->m_InheritedData.m_LetterSpacing.Set( 349 FDE_CSSLengthUnit::Normal); 350 } else if (eType == FDE_CSSPrimitiveType::Number) { 351 if (pValue.As<CFDE_CSSNumberValue>()->Kind() == 352 FDE_CSSNumberType::Percent) { 353 break; 354 } 355 356 SetLengthWithPercent(pComputedStyle->m_InheritedData.m_LetterSpacing, 357 eType, pValue, 358 pComputedStyle->m_InheritedData.m_fFontSize); 359 } 360 break; 361 case FDE_CSSProperty::WordSpacing: 362 if (eType == FDE_CSSPrimitiveType::Enum) { 363 pComputedStyle->m_InheritedData.m_WordSpacing.Set( 364 FDE_CSSLengthUnit::Normal); 365 } else if (eType == FDE_CSSPrimitiveType::Number) { 366 if (pValue.As<CFDE_CSSNumberValue>()->Kind() == 367 FDE_CSSNumberType::Percent) { 368 break; 369 } 370 SetLengthWithPercent(pComputedStyle->m_InheritedData.m_WordSpacing, 371 eType, pValue, 372 pComputedStyle->m_InheritedData.m_fFontSize); 373 } 374 break; 375 case FDE_CSSProperty::Top: 376 SetLengthWithPercent(pComputedStyle->m_NonInheritedData.m_Top, eType, 377 pValue, 378 pComputedStyle->m_InheritedData.m_fFontSize); 379 break; 380 case FDE_CSSProperty::Bottom: 381 SetLengthWithPercent(pComputedStyle->m_NonInheritedData.m_Bottom, eType, 382 pValue, 383 pComputedStyle->m_InheritedData.m_fFontSize); 384 break; 385 case FDE_CSSProperty::Left: 386 SetLengthWithPercent(pComputedStyle->m_NonInheritedData.m_Left, eType, 387 pValue, 388 pComputedStyle->m_InheritedData.m_fFontSize); 389 break; 390 case FDE_CSSProperty::Right: 391 SetLengthWithPercent(pComputedStyle->m_NonInheritedData.m_Right, eType, 392 pValue, 393 pComputedStyle->m_InheritedData.m_fFontSize); 394 break; 395 default: 396 break; 397 } 398 } else if (pValue->GetType() == FDE_CSSPrimitiveType::List) { 399 CFX_RetainPtr<CFDE_CSSValueList> pList = pValue.As<CFDE_CSSValueList>(); 400 int32_t iCount = pList->CountValues(); 401 if (iCount > 0) { 402 switch (eProperty) { 403 case FDE_CSSProperty::FontFamily: 404 pComputedStyle->m_InheritedData.m_pFontFamily = pList; 405 break; 406 case FDE_CSSProperty::TextDecoration: 407 pComputedStyle->m_NonInheritedData.m_dwTextDecoration = 408 ToTextDecoration(pList); 409 break; 410 default: 411 break; 412 } 413 } 414 } else { 415 ASSERT(false); 416 } 417 } 418 419 FDE_CSSDisplay CFDE_CSSStyleSelector::ToDisplay(FDE_CSSPropertyValue eValue) { 420 switch (eValue) { 421 case FDE_CSSPropertyValue::Block: 422 return FDE_CSSDisplay::Block; 423 case FDE_CSSPropertyValue::None: 424 return FDE_CSSDisplay::None; 425 case FDE_CSSPropertyValue::ListItem: 426 return FDE_CSSDisplay::ListItem; 427 case FDE_CSSPropertyValue::InlineTable: 428 return FDE_CSSDisplay::InlineTable; 429 case FDE_CSSPropertyValue::InlineBlock: 430 return FDE_CSSDisplay::InlineBlock; 431 case FDE_CSSPropertyValue::Inline: 432 default: 433 return FDE_CSSDisplay::Inline; 434 } 435 } 436 437 FDE_CSSTextAlign CFDE_CSSStyleSelector::ToTextAlign( 438 FDE_CSSPropertyValue eValue) { 439 switch (eValue) { 440 case FDE_CSSPropertyValue::Center: 441 return FDE_CSSTextAlign::Center; 442 case FDE_CSSPropertyValue::Right: 443 return FDE_CSSTextAlign::Right; 444 case FDE_CSSPropertyValue::Justify: 445 return FDE_CSSTextAlign::Justify; 446 case FDE_CSSPropertyValue::Left: 447 default: 448 return FDE_CSSTextAlign::Left; 449 } 450 } 451 452 uint16_t CFDE_CSSStyleSelector::ToFontWeight(FDE_CSSPropertyValue eValue) { 453 switch (eValue) { 454 case FDE_CSSPropertyValue::Bold: 455 return 700; 456 case FDE_CSSPropertyValue::Bolder: 457 return 900; 458 case FDE_CSSPropertyValue::Lighter: 459 return 200; 460 case FDE_CSSPropertyValue::Normal: 461 default: 462 return 400; 463 } 464 } 465 466 FDE_CSSFontStyle CFDE_CSSStyleSelector::ToFontStyle( 467 FDE_CSSPropertyValue eValue) { 468 switch (eValue) { 469 case FDE_CSSPropertyValue::Italic: 470 case FDE_CSSPropertyValue::Oblique: 471 return FDE_CSSFontStyle::Italic; 472 default: 473 return FDE_CSSFontStyle::Normal; 474 } 475 } 476 477 bool CFDE_CSSStyleSelector::SetLengthWithPercent( 478 FDE_CSSLength& width, 479 FDE_CSSPrimitiveType eType, 480 const CFX_RetainPtr<CFDE_CSSValue>& pValue, 481 FX_FLOAT fFontSize) { 482 if (eType == FDE_CSSPrimitiveType::Number) { 483 CFX_RetainPtr<CFDE_CSSNumberValue> v = pValue.As<CFDE_CSSNumberValue>(); 484 if (v->Kind() == FDE_CSSNumberType::Percent) { 485 width.Set(FDE_CSSLengthUnit::Percent, 486 pValue.As<CFDE_CSSNumberValue>()->Value() / 100.0f); 487 return width.NonZero(); 488 } 489 490 FX_FLOAT fValue = v->Apply(fFontSize); 491 width.Set(FDE_CSSLengthUnit::Point, fValue); 492 return width.NonZero(); 493 } else if (eType == FDE_CSSPrimitiveType::Enum) { 494 switch (pValue.As<CFDE_CSSEnumValue>()->Value()) { 495 case FDE_CSSPropertyValue::Auto: 496 width.Set(FDE_CSSLengthUnit::Auto); 497 return true; 498 case FDE_CSSPropertyValue::None: 499 width.Set(FDE_CSSLengthUnit::None); 500 return true; 501 case FDE_CSSPropertyValue::Thin: 502 width.Set(FDE_CSSLengthUnit::Point, 2); 503 return true; 504 case FDE_CSSPropertyValue::Medium: 505 width.Set(FDE_CSSLengthUnit::Point, 3); 506 return true; 507 case FDE_CSSPropertyValue::Thick: 508 width.Set(FDE_CSSLengthUnit::Point, 4); 509 return true; 510 default: 511 return false; 512 } 513 } 514 return false; 515 } 516 517 FX_FLOAT CFDE_CSSStyleSelector::ToFontSize(FDE_CSSPropertyValue eValue, 518 FX_FLOAT fCurFontSize) { 519 switch (eValue) { 520 case FDE_CSSPropertyValue::XxSmall: 521 return m_fDefFontSize / 1.2f / 1.2f / 1.2f; 522 case FDE_CSSPropertyValue::XSmall: 523 return m_fDefFontSize / 1.2f / 1.2f; 524 case FDE_CSSPropertyValue::Small: 525 return m_fDefFontSize / 1.2f; 526 case FDE_CSSPropertyValue::Medium: 527 return m_fDefFontSize; 528 case FDE_CSSPropertyValue::Large: 529 return m_fDefFontSize * 1.2f; 530 case FDE_CSSPropertyValue::XLarge: 531 return m_fDefFontSize * 1.2f * 1.2f; 532 case FDE_CSSPropertyValue::XxLarge: 533 return m_fDefFontSize * 1.2f * 1.2f * 1.2f; 534 case FDE_CSSPropertyValue::Larger: 535 return fCurFontSize * 1.2f; 536 case FDE_CSSPropertyValue::Smaller: 537 return fCurFontSize / 1.2f; 538 default: 539 return fCurFontSize; 540 } 541 } 542 543 FDE_CSSVerticalAlign CFDE_CSSStyleSelector::ToVerticalAlign( 544 FDE_CSSPropertyValue eValue) { 545 switch (eValue) { 546 case FDE_CSSPropertyValue::Middle: 547 return FDE_CSSVerticalAlign::Middle; 548 case FDE_CSSPropertyValue::Bottom: 549 return FDE_CSSVerticalAlign::Bottom; 550 case FDE_CSSPropertyValue::Super: 551 return FDE_CSSVerticalAlign::Super; 552 case FDE_CSSPropertyValue::Sub: 553 return FDE_CSSVerticalAlign::Sub; 554 case FDE_CSSPropertyValue::Top: 555 return FDE_CSSVerticalAlign::Top; 556 case FDE_CSSPropertyValue::TextTop: 557 return FDE_CSSVerticalAlign::TextTop; 558 case FDE_CSSPropertyValue::TextBottom: 559 return FDE_CSSVerticalAlign::TextBottom; 560 case FDE_CSSPropertyValue::Baseline: 561 default: 562 return FDE_CSSVerticalAlign::Baseline; 563 } 564 } 565 566 uint32_t CFDE_CSSStyleSelector::ToTextDecoration( 567 const CFX_RetainPtr<CFDE_CSSValueList>& pValue) { 568 uint32_t dwDecoration = 0; 569 for (int32_t i = pValue->CountValues() - 1; i >= 0; --i) { 570 const CFX_RetainPtr<CFDE_CSSValue> pVal = pValue->GetValue(i); 571 if (pVal->GetType() != FDE_CSSPrimitiveType::Enum) 572 continue; 573 574 switch (pVal.As<CFDE_CSSEnumValue>()->Value()) { 575 case FDE_CSSPropertyValue::Underline: 576 dwDecoration |= FDE_CSSTEXTDECORATION_Underline; 577 break; 578 case FDE_CSSPropertyValue::LineThrough: 579 dwDecoration |= FDE_CSSTEXTDECORATION_LineThrough; 580 break; 581 case FDE_CSSPropertyValue::Overline: 582 dwDecoration |= FDE_CSSTEXTDECORATION_Overline; 583 break; 584 case FDE_CSSPropertyValue::Blink: 585 dwDecoration |= FDE_CSSTEXTDECORATION_Blink; 586 break; 587 case FDE_CSSPropertyValue::Double: 588 dwDecoration |= FDE_CSSTEXTDECORATION_Double; 589 break; 590 default: 591 break; 592 } 593 } 594 return dwDecoration; 595 } 596 597 FDE_CSSFontVariant CFDE_CSSStyleSelector::ToFontVariant( 598 FDE_CSSPropertyValue eValue) { 599 return eValue == FDE_CSSPropertyValue::SmallCaps 600 ? FDE_CSSFontVariant::SmallCaps 601 : FDE_CSSFontVariant::Normal; 602 } 603