// Copyright 2014 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com

#include "core/fxcrt/css/cfx_cssstyleselector.h"

#include <algorithm>
#include <utility>

#include "core/fxcrt/check.h"
#include "core/fxcrt/containers/adapters.h"
#include "core/fxcrt/css/cfx_csscolorvalue.h"
#include "core/fxcrt/css/cfx_csscomputedstyle.h"
#include "core/fxcrt/css/cfx_csscustomproperty.h"
#include "core/fxcrt/css/cfx_cssdeclaration.h"
#include "core/fxcrt/css/cfx_cssenumvalue.h"
#include "core/fxcrt/css/cfx_csspropertyholder.h"
#include "core/fxcrt/css/cfx_cssselector.h"
#include "core/fxcrt/css/cfx_cssstylesheet.h"
#include "core/fxcrt/css/cfx_csssyntaxparser.h"
#include "core/fxcrt/css/cfx_cssvaluelist.h"

CFX_CSSStyleSelector::CFX_CSSStyleSelector() = default;

CFX_CSSStyleSelector::~CFX_CSSStyleSelector() = default;

void CFX_CSSStyleSelector::SetDefaultFontSize(float fFontSize) {
  DCHECK(fFontSize > 0);
  m_fDefaultFontSize = fFontSize;
}

RetainPtr<CFX_CSSComputedStyle> CFX_CSSStyleSelector::CreateComputedStyle(
    const CFX_CSSComputedStyle* pParentStyle) {
  auto pStyle = pdfium::MakeRetain<CFX_CSSComputedStyle>();
  if (pParentStyle)
    pStyle->m_InheritedData = pParentStyle->m_InheritedData;
  return pStyle;
}

void CFX_CSSStyleSelector::SetUAStyleSheet(
    std::unique_ptr<CFX_CSSStyleSheet> pSheet) {
  m_UAStyles = std::move(pSheet);
}

void CFX_CSSStyleSelector::UpdateStyleIndex() {
  m_UARules.SetRulesFromSheet(m_UAStyles.get());
}

std::vector<const CFX_CSSDeclaration*> CFX_CSSStyleSelector::MatchDeclarations(
    const WideString& tagname) {
  std::vector<const CFX_CSSDeclaration*> matchedDecls;
  if (tagname.IsEmpty())
    return matchedDecls;

  auto* rules = m_UARules.GetTagRuleData(tagname);
  if (!rules)
    return matchedDecls;

  for (const auto& d : *rules) {
    if (MatchSelector(tagname, d->pSelector))
      matchedDecls.push_back(d->pDeclaration);
  }
  return matchedDecls;
}

bool CFX_CSSStyleSelector::MatchSelector(const WideString& tagname,
                                         CFX_CSSSelector* pSel) {
  // TODO(dsinclair): The code only supports a single level of selector at this
  // point. None of the code using selectors required the complexity so lets
  // just say we don't support them to simplify the code for now.
  if (!pSel || pSel->next_selector() || pSel->is_descendant())
    return false;
  return pSel->name_hash() == FX_HashCode_GetLoweredW(tagname.AsStringView());
}

void CFX_CSSStyleSelector::ComputeStyle(
    const std::vector<const CFX_CSSDeclaration*>& declArray,
    const WideString& styleString,
    const WideString& alignString,
    CFX_CSSComputedStyle* pDest) {
  std::unique_ptr<CFX_CSSDeclaration> pDecl;
  if (!styleString.IsEmpty() || !alignString.IsEmpty()) {
    pDecl = std::make_unique<CFX_CSSDeclaration>();

    if (!styleString.IsEmpty())
      AppendInlineStyle(pDecl.get(), styleString);
    if (!alignString.IsEmpty()) {
      pDecl->AddProperty(
          CFX_CSSData::GetPropertyByEnum(CFX_CSSProperty::TextAlign),
          alignString.AsStringView());
    }
  }
  ApplyDeclarations(declArray, pDecl.get(), pDest);
}

void CFX_CSSStyleSelector::ApplyDeclarations(
    const std::vector<const CFX_CSSDeclaration*>& declArray,
    const CFX_CSSDeclaration* extraDecl,
    CFX_CSSComputedStyle* pComputedStyle) {
  std::vector<const CFX_CSSPropertyHolder*> importants;
  std::vector<const CFX_CSSPropertyHolder*> normals;
  std::vector<const CFX_CSSCustomProperty*> customs;

  for (auto* decl : declArray)
    ExtractValues(decl, &importants, &normals, &customs);

  if (extraDecl)
    ExtractValues(extraDecl, &importants, &normals, &customs);

  for (auto* prop : normals)
    ApplyProperty(prop->eProperty, prop->pValue, pComputedStyle);

  for (auto* prop : customs)
    pComputedStyle->AddCustomStyle(*prop);

  for (auto* prop : importants)
    ApplyProperty(prop->eProperty, prop->pValue, pComputedStyle);
}

void CFX_CSSStyleSelector::ExtractValues(
    const CFX_CSSDeclaration* decl,
    std::vector<const CFX_CSSPropertyHolder*>* importants,
    std::vector<const CFX_CSSPropertyHolder*>* normals,
    std::vector<const CFX_CSSCustomProperty*>* custom) {
  for (const auto& holder : *decl) {
    if (holder->bImportant)
      importants->push_back(holder.get());
    else
      normals->push_back(holder.get());
  }
  for (auto it = decl->custom_begin(); it != decl->custom_end(); it++)
    custom->push_back(it->get());
}

void CFX_CSSStyleSelector::AppendInlineStyle(CFX_CSSDeclaration* pDecl,
                                             const WideString& style) {
  DCHECK(pDecl);
  DCHECK(!style.IsEmpty());

  auto pSyntax = std::make_unique<CFX_CSSSyntaxParser>(style.AsStringView());
  pSyntax->SetParseOnlyDeclarations();

  int32_t iLen2 = 0;
  const CFX_CSSData::Property* property = nullptr;
  WideString wsName;
  while (true) {
    CFX_CSSSyntaxParser::Status eStatus = pSyntax->DoSyntaxParse();
    if (eStatus == CFX_CSSSyntaxParser::Status::kPropertyName) {
      WideStringView strValue = pSyntax->GetCurrentString();
      property = CFX_CSSData::GetPropertyByName(strValue);
      if (!property)
        wsName = WideString(strValue);
    } else if (eStatus == CFX_CSSSyntaxParser::Status::kPropertyValue) {
      if (property || iLen2 > 0) {
        WideStringView strValue = pSyntax->GetCurrentString();
        if (!strValue.IsEmpty()) {
          if (property)
            pDecl->AddProperty(property, strValue);
          else if (iLen2 > 0)
            pDecl->AddProperty(wsName, WideString(strValue));
        }
      }
    } else {
      break;
    }
  }
}

void CFX_CSSStyleSelector::ApplyProperty(CFX_CSSProperty eProperty,
                                         const RetainPtr<CFX_CSSValue>& pValue,
                                         CFX_CSSComputedStyle* pComputedStyle) {
  const CFX_CSSValue::PrimitiveType eType = pValue->GetType();
  if (eType == CFX_CSSValue::PrimitiveType::kList) {
    RetainPtr<CFX_CSSValueList> value_list = pValue.As<CFX_CSSValueList>();
    if (!value_list->values().empty()) {
      switch (eProperty) {
        case CFX_CSSProperty::FontFamily:
          pComputedStyle->m_InheritedData.m_pFontFamily = std::move(value_list);
          break;
        case CFX_CSSProperty::TextDecoration:
          pComputedStyle->m_NonInheritedData.m_dwTextDecoration =
              ToTextDecoration(value_list);
          break;
        default:
          break;
      }
    }
    return;
  }

  switch (eProperty) {
    case CFX_CSSProperty::Display:
      if (eType == CFX_CSSValue::PrimitiveType::kEnum) {
        pComputedStyle->m_NonInheritedData.m_eDisplay =
            ToDisplay(pValue.AsRaw<CFX_CSSEnumValue>()->Value());
      }
      break;
    case CFX_CSSProperty::FontSize: {
      float& fFontSize = pComputedStyle->m_InheritedData.m_fFontSize;
      if (eType == CFX_CSSValue::PrimitiveType::kNumber) {
        fFontSize = pValue.AsRaw<CFX_CSSNumberValue>()->Apply(fFontSize);
      } else if (eType == CFX_CSSValue::PrimitiveType::kEnum) {
        fFontSize =
            ToFontSize(pValue.AsRaw<CFX_CSSEnumValue>()->Value(), fFontSize);
      }
    } break;
    case CFX_CSSProperty::LineHeight:
      if (eType == CFX_CSSValue::PrimitiveType::kNumber) {
        RetainPtr<CFX_CSSNumberValue> v = pValue.As<CFX_CSSNumberValue>();
        if (v->unit() == CFX_CSSNumber::Unit::kNumber) {
          pComputedStyle->m_InheritedData.m_fLineHeight =
              v->value() * pComputedStyle->m_InheritedData.m_fFontSize;
        } else {
          pComputedStyle->m_InheritedData.m_fLineHeight =
              v->Apply(pComputedStyle->m_InheritedData.m_fFontSize);
        }
      }
      break;
    case CFX_CSSProperty::TextAlign:
      if (eType == CFX_CSSValue::PrimitiveType::kEnum) {
        pComputedStyle->m_InheritedData.m_eTextAlign =
            ToTextAlign(pValue.AsRaw<CFX_CSSEnumValue>()->Value());
      }
      break;
    case CFX_CSSProperty::TextIndent:
      SetLengthWithPercent(pComputedStyle->m_InheritedData.m_TextIndent, eType,
                           pValue, pComputedStyle->m_InheritedData.m_fFontSize);
      break;
    case CFX_CSSProperty::FontWeight:
      if (eType == CFX_CSSValue::PrimitiveType::kEnum) {
        pComputedStyle->m_InheritedData.m_wFontWeight =
            ToFontWeight(pValue.AsRaw<CFX_CSSEnumValue>()->Value());
      } else if (eType == CFX_CSSValue::PrimitiveType::kNumber) {
        int32_t iValue =
            static_cast<int32_t>(pValue.AsRaw<CFX_CSSNumberValue>()->value()) /
            100;
        if (iValue >= 1 && iValue <= 9) {
          pComputedStyle->m_InheritedData.m_wFontWeight = iValue * 100;
        }
      }
      break;
    case CFX_CSSProperty::FontStyle:
      if (eType == CFX_CSSValue::PrimitiveType::kEnum) {
        pComputedStyle->m_InheritedData.m_eFontStyle =
            ToFontStyle(pValue.AsRaw<CFX_CSSEnumValue>()->Value());
      }
      break;
    case CFX_CSSProperty::Color:
      if (eType == CFX_CSSValue::PrimitiveType::kRGB) {
        pComputedStyle->m_InheritedData.m_dwFontColor =
            pValue.AsRaw<CFX_CSSColorValue>()->Value();
      }
      break;
    case CFX_CSSProperty::MarginLeft:
      if (SetLengthWithPercent(
              pComputedStyle->m_NonInheritedData.m_MarginWidth.left, eType,
              pValue, pComputedStyle->m_InheritedData.m_fFontSize)) {
        pComputedStyle->m_NonInheritedData.m_bHasMargin = true;
      }
      break;
    case CFX_CSSProperty::MarginTop:
      if (SetLengthWithPercent(
              pComputedStyle->m_NonInheritedData.m_MarginWidth.top, eType,
              pValue, pComputedStyle->m_InheritedData.m_fFontSize)) {
        pComputedStyle->m_NonInheritedData.m_bHasMargin = true;
      }
      break;
    case CFX_CSSProperty::MarginRight:
      if (SetLengthWithPercent(
              pComputedStyle->m_NonInheritedData.m_MarginWidth.right, eType,
              pValue, pComputedStyle->m_InheritedData.m_fFontSize)) {
        pComputedStyle->m_NonInheritedData.m_bHasMargin = true;
      }
      break;
    case CFX_CSSProperty::MarginBottom:
      if (SetLengthWithPercent(
              pComputedStyle->m_NonInheritedData.m_MarginWidth.bottom, eType,
              pValue, pComputedStyle->m_InheritedData.m_fFontSize)) {
        pComputedStyle->m_NonInheritedData.m_bHasMargin = true;
      }
      break;
    case CFX_CSSProperty::PaddingLeft:
      if (SetLengthWithPercent(
              pComputedStyle->m_NonInheritedData.m_PaddingWidth.left, eType,
              pValue, pComputedStyle->m_InheritedData.m_fFontSize)) {
        pComputedStyle->m_NonInheritedData.m_bHasPadding = true;
      }
      break;
    case CFX_CSSProperty::PaddingTop:
      if (SetLengthWithPercent(
              pComputedStyle->m_NonInheritedData.m_PaddingWidth.top, eType,
              pValue, pComputedStyle->m_InheritedData.m_fFontSize)) {
        pComputedStyle->m_NonInheritedData.m_bHasPadding = true;
      }
      break;
    case CFX_CSSProperty::PaddingRight:
      if (SetLengthWithPercent(
              pComputedStyle->m_NonInheritedData.m_PaddingWidth.right, eType,
              pValue, pComputedStyle->m_InheritedData.m_fFontSize)) {
        pComputedStyle->m_NonInheritedData.m_bHasPadding = true;
      }
      break;
    case CFX_CSSProperty::PaddingBottom:
      if (SetLengthWithPercent(
              pComputedStyle->m_NonInheritedData.m_PaddingWidth.bottom, eType,
              pValue, pComputedStyle->m_InheritedData.m_fFontSize)) {
        pComputedStyle->m_NonInheritedData.m_bHasPadding = true;
      }
      break;
    case CFX_CSSProperty::BorderLeftWidth:
      if (SetLengthWithPercent(
              pComputedStyle->m_NonInheritedData.m_BorderWidth.left, eType,
              pValue, pComputedStyle->m_InheritedData.m_fFontSize)) {
        pComputedStyle->m_NonInheritedData.m_bHasBorder = true;
      }
      break;
    case CFX_CSSProperty::BorderTopWidth:
      if (SetLengthWithPercent(
              pComputedStyle->m_NonInheritedData.m_BorderWidth.top, eType,
              pValue, pComputedStyle->m_InheritedData.m_fFontSize)) {
        pComputedStyle->m_NonInheritedData.m_bHasBorder = true;
      }
      break;
    case CFX_CSSProperty::BorderRightWidth:
      if (SetLengthWithPercent(
              pComputedStyle->m_NonInheritedData.m_BorderWidth.right, eType,
              pValue, pComputedStyle->m_InheritedData.m_fFontSize)) {
        pComputedStyle->m_NonInheritedData.m_bHasBorder = true;
      }
      break;
    case CFX_CSSProperty::BorderBottomWidth:
      if (SetLengthWithPercent(
              pComputedStyle->m_NonInheritedData.m_BorderWidth.bottom, eType,
              pValue, pComputedStyle->m_InheritedData.m_fFontSize)) {
        pComputedStyle->m_NonInheritedData.m_bHasBorder = true;
      }
      break;
    case CFX_CSSProperty::VerticalAlign:
      if (eType == CFX_CSSValue::PrimitiveType::kEnum) {
        pComputedStyle->m_NonInheritedData.m_eVerticalAlignType =
            ToVerticalAlign(pValue.AsRaw<CFX_CSSEnumValue>()->Value());
      } else if (eType == CFX_CSSValue::PrimitiveType::kNumber) {
        pComputedStyle->m_NonInheritedData.m_eVerticalAlignType =
            CFX_CSSVerticalAlign::Number;
        pComputedStyle->m_NonInheritedData.m_fVerticalAlign =
            pValue.AsRaw<CFX_CSSNumberValue>()->Apply(
                pComputedStyle->m_InheritedData.m_fFontSize);
      }
      break;
    case CFX_CSSProperty::FontVariant:
      if (eType == CFX_CSSValue::PrimitiveType::kEnum) {
        pComputedStyle->m_InheritedData.m_eFontVariant =
            ToFontVariant(pValue.AsRaw<CFX_CSSEnumValue>()->Value());
      }
      break;
    case CFX_CSSProperty::LetterSpacing:
      if (eType == CFX_CSSValue::PrimitiveType::kEnum) {
        pComputedStyle->m_InheritedData.m_LetterSpacing.Set(
            CFX_CSSLengthUnit::Normal);
      } else if (eType == CFX_CSSValue::PrimitiveType::kNumber) {
        if (pValue.AsRaw<CFX_CSSNumberValue>()->unit() ==
            CFX_CSSNumber::Unit::kPercent) {
          break;
        }

        SetLengthWithPercent(pComputedStyle->m_InheritedData.m_LetterSpacing,
                             eType, pValue,
                             pComputedStyle->m_InheritedData.m_fFontSize);
      }
      break;
    case CFX_CSSProperty::WordSpacing:
      if (eType == CFX_CSSValue::PrimitiveType::kEnum) {
        pComputedStyle->m_InheritedData.m_WordSpacing.Set(
            CFX_CSSLengthUnit::Normal);
      } else if (eType == CFX_CSSValue::PrimitiveType::kNumber) {
        if (pValue.AsRaw<CFX_CSSNumberValue>()->unit() ==
            CFX_CSSNumber::Unit::kPercent) {
          break;
        }
        SetLengthWithPercent(pComputedStyle->m_InheritedData.m_WordSpacing,
                             eType, pValue,
                             pComputedStyle->m_InheritedData.m_fFontSize);
      }
      break;
    case CFX_CSSProperty::Top:
      SetLengthWithPercent(pComputedStyle->m_NonInheritedData.m_Top, eType,
                           pValue, pComputedStyle->m_InheritedData.m_fFontSize);
      break;
    case CFX_CSSProperty::Bottom:
      SetLengthWithPercent(pComputedStyle->m_NonInheritedData.m_Bottom, eType,
                           pValue, pComputedStyle->m_InheritedData.m_fFontSize);
      break;
    case CFX_CSSProperty::Left:
      SetLengthWithPercent(pComputedStyle->m_NonInheritedData.m_Left, eType,
                           pValue, pComputedStyle->m_InheritedData.m_fFontSize);
      break;
    case CFX_CSSProperty::Right:
      SetLengthWithPercent(pComputedStyle->m_NonInheritedData.m_Right, eType,
                           pValue, pComputedStyle->m_InheritedData.m_fFontSize);
      break;
    default:
      break;
  }
}

CFX_CSSDisplay CFX_CSSStyleSelector::ToDisplay(CFX_CSSPropertyValue eValue) {
  switch (eValue) {
    case CFX_CSSPropertyValue::Block:
      return CFX_CSSDisplay::Block;
    case CFX_CSSPropertyValue::None:
      return CFX_CSSDisplay::None;
    case CFX_CSSPropertyValue::ListItem:
      return CFX_CSSDisplay::ListItem;
    case CFX_CSSPropertyValue::InlineTable:
      return CFX_CSSDisplay::InlineTable;
    case CFX_CSSPropertyValue::InlineBlock:
      return CFX_CSSDisplay::InlineBlock;
    case CFX_CSSPropertyValue::Inline:
    default:
      return CFX_CSSDisplay::Inline;
  }
}

CFX_CSSTextAlign CFX_CSSStyleSelector::ToTextAlign(
    CFX_CSSPropertyValue eValue) {
  switch (eValue) {
    case CFX_CSSPropertyValue::Center:
      return CFX_CSSTextAlign::Center;
    case CFX_CSSPropertyValue::Right:
      return CFX_CSSTextAlign::Right;
    case CFX_CSSPropertyValue::Justify:
      return CFX_CSSTextAlign::Justify;
    case CFX_CSSPropertyValue::Left:
    default:
      return CFX_CSSTextAlign::Left;
  }
}

uint16_t CFX_CSSStyleSelector::ToFontWeight(CFX_CSSPropertyValue eValue) {
  switch (eValue) {
    case CFX_CSSPropertyValue::Bold:
      return 700;
    case CFX_CSSPropertyValue::Bolder:
      return 900;
    case CFX_CSSPropertyValue::Lighter:
      return 200;
    case CFX_CSSPropertyValue::Normal:
    default:
      return 400;
  }
}

CFX_CSSFontStyle CFX_CSSStyleSelector::ToFontStyle(
    CFX_CSSPropertyValue eValue) {
  switch (eValue) {
    case CFX_CSSPropertyValue::Italic:
    case CFX_CSSPropertyValue::Oblique:
      return CFX_CSSFontStyle::Italic;
    default:
      return CFX_CSSFontStyle::Normal;
  }
}

bool CFX_CSSStyleSelector::SetLengthWithPercent(
    CFX_CSSLength& width,
    CFX_CSSValue::PrimitiveType eType,
    const RetainPtr<CFX_CSSValue>& pValue,
    float fFontSize) {
  if (eType == CFX_CSSValue::PrimitiveType::kNumber) {
    RetainPtr<CFX_CSSNumberValue> v = pValue.As<CFX_CSSNumberValue>();
    if (v->unit() == CFX_CSSNumber::Unit::kPercent) {
      width.Set(CFX_CSSLengthUnit::Percent,
                pValue.AsRaw<CFX_CSSNumberValue>()->value() / 100.0f);
      return width.NonZero();
    }

    float fValue = v->Apply(fFontSize);
    width.Set(CFX_CSSLengthUnit::Point, fValue);
    return width.NonZero();
  } else if (eType == CFX_CSSValue::PrimitiveType::kEnum) {
    switch (pValue.AsRaw<CFX_CSSEnumValue>()->Value()) {
      case CFX_CSSPropertyValue::Auto:
        width.Set(CFX_CSSLengthUnit::Auto);
        return true;
      case CFX_CSSPropertyValue::None:
        width.Set(CFX_CSSLengthUnit::None);
        return true;
      case CFX_CSSPropertyValue::Thin:
        width.Set(CFX_CSSLengthUnit::Point, 2);
        return true;
      case CFX_CSSPropertyValue::Medium:
        width.Set(CFX_CSSLengthUnit::Point, 3);
        return true;
      case CFX_CSSPropertyValue::Thick:
        width.Set(CFX_CSSLengthUnit::Point, 4);
        return true;
      default:
        return false;
    }
  }
  return false;
}

float CFX_CSSStyleSelector::ToFontSize(CFX_CSSPropertyValue eValue,
                                       float fCurFontSize) {
  switch (eValue) {
    case CFX_CSSPropertyValue::XxSmall:
      return m_fDefaultFontSize / 1.2f / 1.2f / 1.2f;
    case CFX_CSSPropertyValue::XSmall:
      return m_fDefaultFontSize / 1.2f / 1.2f;
    case CFX_CSSPropertyValue::Small:
      return m_fDefaultFontSize / 1.2f;
    case CFX_CSSPropertyValue::Medium:
      return m_fDefaultFontSize;
    case CFX_CSSPropertyValue::Large:
      return m_fDefaultFontSize * 1.2f;
    case CFX_CSSPropertyValue::XLarge:
      return m_fDefaultFontSize * 1.2f * 1.2f;
    case CFX_CSSPropertyValue::XxLarge:
      return m_fDefaultFontSize * 1.2f * 1.2f * 1.2f;
    case CFX_CSSPropertyValue::Larger:
      return fCurFontSize * 1.2f;
    case CFX_CSSPropertyValue::Smaller:
      return fCurFontSize / 1.2f;
    default:
      return fCurFontSize;
  }
}

CFX_CSSVerticalAlign CFX_CSSStyleSelector::ToVerticalAlign(
    CFX_CSSPropertyValue eValue) {
  switch (eValue) {
    case CFX_CSSPropertyValue::Middle:
      return CFX_CSSVerticalAlign::Middle;
    case CFX_CSSPropertyValue::Bottom:
      return CFX_CSSVerticalAlign::Bottom;
    case CFX_CSSPropertyValue::Super:
      return CFX_CSSVerticalAlign::Super;
    case CFX_CSSPropertyValue::Sub:
      return CFX_CSSVerticalAlign::Sub;
    case CFX_CSSPropertyValue::Top:
      return CFX_CSSVerticalAlign::Top;
    case CFX_CSSPropertyValue::TextTop:
      return CFX_CSSVerticalAlign::TextTop;
    case CFX_CSSPropertyValue::TextBottom:
      return CFX_CSSVerticalAlign::TextBottom;
    case CFX_CSSPropertyValue::Baseline:
    default:
      return CFX_CSSVerticalAlign::Baseline;
  }
}

Mask<CFX_CSSTEXTDECORATION> CFX_CSSStyleSelector::ToTextDecoration(
    const RetainPtr<CFX_CSSValueList>& pValue) {
  Mask<CFX_CSSTEXTDECORATION> dwDecoration;
  for (const RetainPtr<CFX_CSSValue>& val :
       pdfium::Reversed(pValue->values())) {
    if (val->GetType() != CFX_CSSValue::PrimitiveType::kEnum)
      continue;

    switch (val.AsRaw<CFX_CSSEnumValue>()->Value()) {
      case CFX_CSSPropertyValue::Underline:
        dwDecoration |= CFX_CSSTEXTDECORATION::kUnderline;
        break;
      case CFX_CSSPropertyValue::LineThrough:
        dwDecoration |= CFX_CSSTEXTDECORATION::kLineThrough;
        break;
      case CFX_CSSPropertyValue::Overline:
        dwDecoration |= CFX_CSSTEXTDECORATION::kOverline;
        break;
      case CFX_CSSPropertyValue::Blink:
        dwDecoration |= CFX_CSSTEXTDECORATION::kBlink;
        break;
      case CFX_CSSPropertyValue::Double:
        dwDecoration |= CFX_CSSTEXTDECORATION::kDouble;
        break;
      default:
        break;
    }
  }
  return dwDecoration;
}

CFX_CSSFontVariant CFX_CSSStyleSelector::ToFontVariant(
    CFX_CSSPropertyValue eValue) {
  return eValue == CFX_CSSPropertyValue::SmallCaps
             ? CFX_CSSFontVariant::SmallCaps
             : CFX_CSSFontVariant::Normal;
}
