// Copyright 2014 PDFium Authors. All rights reserved.
// 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 "xfa/fde/css/cfde_cssstyleselector.h"

#include <algorithm>
#include <utility>

#include "third_party/base/logging.h"
#include "third_party/base/ptr_util.h"
#include "xfa/fde/css/cfde_csscolorvalue.h"
#include "xfa/fde/css/cfde_csscomputedstyle.h"
#include "xfa/fde/css/cfde_csscustomproperty.h"
#include "xfa/fde/css/cfde_cssdeclaration.h"
#include "xfa/fde/css/cfde_cssenumvalue.h"
#include "xfa/fde/css/cfde_csspropertyholder.h"
#include "xfa/fde/css/cfde_cssselector.h"
#include "xfa/fde/css/cfde_cssstylesheet.h"
#include "xfa/fde/css/cfde_csssyntaxparser.h"
#include "xfa/fde/css/cfde_cssvaluelist.h"
#include "xfa/fxfa/cxfa_csstagprovider.h"

CFDE_CSSStyleSelector::CFDE_CSSStyleSelector(CFGAS_FontMgr* pFontMgr)
    : m_pFontMgr(pFontMgr), m_fDefFontSize(12.0f) {}

CFDE_CSSStyleSelector::~CFDE_CSSStyleSelector() {}

void CFDE_CSSStyleSelector::SetDefFontSize(float fFontSize) {
  ASSERT(fFontSize > 0);
  m_fDefFontSize = fFontSize;
}

CFX_RetainPtr<CFDE_CSSComputedStyle> CFDE_CSSStyleSelector::CreateComputedStyle(
    CFDE_CSSComputedStyle* pParentStyle) {
  auto pStyle = pdfium::MakeRetain<CFDE_CSSComputedStyle>();
  if (pParentStyle)
    pStyle->m_InheritedData = pParentStyle->m_InheritedData;
  return pStyle;
}

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

void CFDE_CSSStyleSelector::UpdateStyleIndex() {
  m_UARules.Clear();
  m_UARules.AddRulesFrom(m_UAStyles.get(), m_pFontMgr.Get());
}

std::vector<const CFDE_CSSDeclaration*>
CFDE_CSSStyleSelector::MatchDeclarations(const CFX_WideString& tagname) {
  std::vector<const CFDE_CSSDeclaration*> matchedDecls;
  if (m_UARules.CountSelectors() == 0 || 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 CFDE_CSSStyleSelector::MatchSelector(const CFX_WideString& tagname,
                                          CFDE_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->GetNextSelector() ||
      pSel->GetType() == FDE_CSSSelectorType::Descendant) {
    return false;
  }
  return pSel->GetNameHash() == FX_HashCode_GetW(tagname.c_str(), true);
}

void CFDE_CSSStyleSelector::ComputeStyle(
    const std::vector<const CFDE_CSSDeclaration*>& declArray,
    const CFX_WideString& styleString,
    const CFX_WideString& alignString,
    CFDE_CSSComputedStyle* pDest) {
  std::unique_ptr<CFDE_CSSDeclaration> pDecl;
  if (!styleString.IsEmpty() || !alignString.IsEmpty()) {
    pDecl = pdfium::MakeUnique<CFDE_CSSDeclaration>();

    if (!styleString.IsEmpty())
      AppendInlineStyle(pDecl.get(), styleString);
    if (!alignString.IsEmpty()) {
      pDecl->AddProperty(FDE_GetCSSPropertyByEnum(FDE_CSSProperty::TextAlign),
                         alignString.AsStringC());
    }
  }
  ApplyDeclarations(declArray, pDecl.get(), pDest);
}

void CFDE_CSSStyleSelector::ApplyDeclarations(
    const std::vector<const CFDE_CSSDeclaration*>& declArray,
    const CFDE_CSSDeclaration* extraDecl,
    CFDE_CSSComputedStyle* pComputedStyle) {
  std::vector<const CFDE_CSSPropertyHolder*> importants;
  std::vector<const CFDE_CSSPropertyHolder*> normals;
  std::vector<const CFDE_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 CFDE_CSSStyleSelector::ExtractValues(
    const CFDE_CSSDeclaration* decl,
    std::vector<const CFDE_CSSPropertyHolder*>* importants,
    std::vector<const CFDE_CSSPropertyHolder*>* normals,
    std::vector<const CFDE_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 CFDE_CSSStyleSelector::AppendInlineStyle(CFDE_CSSDeclaration* pDecl,
                                              const CFX_WideString& style) {
  ASSERT(pDecl && !style.IsEmpty());

  auto pSyntax = pdfium::MakeUnique<CFDE_CSSSyntaxParser>(
      style.c_str(), style.GetLength(), 32, true);
  int32_t iLen2 = 0;
  const FDE_CSSPropertyTable* table = nullptr;
  CFX_WideString wsName;
  while (1) {
    FDE_CSSSyntaxStatus eStatus = pSyntax->DoSyntaxParse();
    if (eStatus == FDE_CSSSyntaxStatus::PropertyName) {
      CFX_WideStringC strValue = pSyntax->GetCurrentString();
      table = FDE_GetCSSPropertyByName(strValue);
      if (!table)
        wsName = CFX_WideString(strValue);
    } else if (eStatus == FDE_CSSSyntaxStatus::PropertyValue) {
      if (table || iLen2 > 0) {
        CFX_WideStringC strValue = pSyntax->GetCurrentString();
        if (!strValue.IsEmpty()) {
          if (table)
            pDecl->AddProperty(table, strValue);
          else if (iLen2 > 0)
            pDecl->AddProperty(wsName, CFX_WideString(strValue));
        }
      }
    } else {
      break;
    }
  }
}

void CFDE_CSSStyleSelector::ApplyProperty(
    FDE_CSSProperty eProperty,
    const CFX_RetainPtr<CFDE_CSSValue>& pValue,
    CFDE_CSSComputedStyle* pComputedStyle) {
  if (pValue->GetType() != FDE_CSSPrimitiveType::List) {
    FDE_CSSPrimitiveType eType = pValue->GetType();
    switch (eProperty) {
      case FDE_CSSProperty::Display:
        if (eType == FDE_CSSPrimitiveType::Enum) {
          pComputedStyle->m_NonInheritedData.m_eDisplay =
              ToDisplay(pValue.As<CFDE_CSSEnumValue>()->Value());
        }
        break;
      case FDE_CSSProperty::FontSize: {
        float& fFontSize = pComputedStyle->m_InheritedData.m_fFontSize;
        if (eType == FDE_CSSPrimitiveType::Number) {
          fFontSize = pValue.As<CFDE_CSSNumberValue>()->Apply(fFontSize);
        } else if (eType == FDE_CSSPrimitiveType::Enum) {
          fFontSize =
              ToFontSize(pValue.As<CFDE_CSSEnumValue>()->Value(), fFontSize);
        }
      } break;
      case FDE_CSSProperty::LineHeight:
        if (eType == FDE_CSSPrimitiveType::Number) {
          CFX_RetainPtr<CFDE_CSSNumberValue> v =
              pValue.As<CFDE_CSSNumberValue>();
          if (v->Kind() == FDE_CSSNumberType::Number) {
            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 FDE_CSSProperty::TextAlign:
        if (eType == FDE_CSSPrimitiveType::Enum) {
          pComputedStyle->m_InheritedData.m_eTextAlign =
              ToTextAlign(pValue.As<CFDE_CSSEnumValue>()->Value());
        }
        break;
      case FDE_CSSProperty::TextIndent:
        SetLengthWithPercent(pComputedStyle->m_InheritedData.m_TextIndent,
                             eType, pValue,
                             pComputedStyle->m_InheritedData.m_fFontSize);
        break;
      case FDE_CSSProperty::FontWeight:
        if (eType == FDE_CSSPrimitiveType::Enum) {
          pComputedStyle->m_InheritedData.m_wFontWeight =
              ToFontWeight(pValue.As<CFDE_CSSEnumValue>()->Value());
        } else if (eType == FDE_CSSPrimitiveType::Number) {
          int32_t iValue =
              (int32_t)pValue.As<CFDE_CSSNumberValue>()->Value() / 100;
          if (iValue >= 1 && iValue <= 9) {
            pComputedStyle->m_InheritedData.m_wFontWeight = iValue * 100;
          }
        }
        break;
      case FDE_CSSProperty::FontStyle:
        if (eType == FDE_CSSPrimitiveType::Enum) {
          pComputedStyle->m_InheritedData.m_eFontStyle =
              ToFontStyle(pValue.As<CFDE_CSSEnumValue>()->Value());
        }
        break;
      case FDE_CSSProperty::Color:
        if (eType == FDE_CSSPrimitiveType::RGB) {
          pComputedStyle->m_InheritedData.m_dwFontColor =
              pValue.As<CFDE_CSSColorValue>()->Value();
        }
        break;
      case FDE_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 FDE_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 FDE_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 FDE_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 FDE_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 FDE_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 FDE_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 FDE_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 FDE_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 FDE_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 FDE_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 FDE_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 FDE_CSSProperty::VerticalAlign:
        if (eType == FDE_CSSPrimitiveType::Enum) {
          pComputedStyle->m_NonInheritedData.m_eVerticalAlign =
              ToVerticalAlign(pValue.As<CFDE_CSSEnumValue>()->Value());
        } else if (eType == FDE_CSSPrimitiveType::Number) {
          pComputedStyle->m_NonInheritedData.m_eVerticalAlign =
              FDE_CSSVerticalAlign::Number;
          pComputedStyle->m_NonInheritedData.m_fVerticalAlign =
              pValue.As<CFDE_CSSNumberValue>()->Apply(
                  pComputedStyle->m_InheritedData.m_fFontSize);
        }
        break;
      case FDE_CSSProperty::FontVariant:
        if (eType == FDE_CSSPrimitiveType::Enum) {
          pComputedStyle->m_InheritedData.m_eFontVariant =
              ToFontVariant(pValue.As<CFDE_CSSEnumValue>()->Value());
        }
        break;
      case FDE_CSSProperty::LetterSpacing:
        if (eType == FDE_CSSPrimitiveType::Enum) {
          pComputedStyle->m_InheritedData.m_LetterSpacing.Set(
              FDE_CSSLengthUnit::Normal);
        } else if (eType == FDE_CSSPrimitiveType::Number) {
          if (pValue.As<CFDE_CSSNumberValue>()->Kind() ==
              FDE_CSSNumberType::Percent) {
            break;
          }

          SetLengthWithPercent(pComputedStyle->m_InheritedData.m_LetterSpacing,
                               eType, pValue,
                               pComputedStyle->m_InheritedData.m_fFontSize);
        }
        break;
      case FDE_CSSProperty::WordSpacing:
        if (eType == FDE_CSSPrimitiveType::Enum) {
          pComputedStyle->m_InheritedData.m_WordSpacing.Set(
              FDE_CSSLengthUnit::Normal);
        } else if (eType == FDE_CSSPrimitiveType::Number) {
          if (pValue.As<CFDE_CSSNumberValue>()->Kind() ==
              FDE_CSSNumberType::Percent) {
            break;
          }
          SetLengthWithPercent(pComputedStyle->m_InheritedData.m_WordSpacing,
                               eType, pValue,
                               pComputedStyle->m_InheritedData.m_fFontSize);
        }
        break;
      case FDE_CSSProperty::Top:
        SetLengthWithPercent(pComputedStyle->m_NonInheritedData.m_Top, eType,
                             pValue,
                             pComputedStyle->m_InheritedData.m_fFontSize);
        break;
      case FDE_CSSProperty::Bottom:
        SetLengthWithPercent(pComputedStyle->m_NonInheritedData.m_Bottom, eType,
                             pValue,
                             pComputedStyle->m_InheritedData.m_fFontSize);
        break;
      case FDE_CSSProperty::Left:
        SetLengthWithPercent(pComputedStyle->m_NonInheritedData.m_Left, eType,
                             pValue,
                             pComputedStyle->m_InheritedData.m_fFontSize);
        break;
      case FDE_CSSProperty::Right:
        SetLengthWithPercent(pComputedStyle->m_NonInheritedData.m_Right, eType,
                             pValue,
                             pComputedStyle->m_InheritedData.m_fFontSize);
        break;
      default:
        break;
    }
  } else if (pValue->GetType() == FDE_CSSPrimitiveType::List) {
    CFX_RetainPtr<CFDE_CSSValueList> pList = pValue.As<CFDE_CSSValueList>();
    int32_t iCount = pList->CountValues();
    if (iCount > 0) {
      switch (eProperty) {
        case FDE_CSSProperty::FontFamily:
          pComputedStyle->m_InheritedData.m_pFontFamily = pList;
          break;
        case FDE_CSSProperty::TextDecoration:
          pComputedStyle->m_NonInheritedData.m_dwTextDecoration =
              ToTextDecoration(pList);
          break;
        default:
          break;
      }
    }
  } else {
    NOTREACHED();
  }
}

FDE_CSSDisplay CFDE_CSSStyleSelector::ToDisplay(FDE_CSSPropertyValue eValue) {
  switch (eValue) {
    case FDE_CSSPropertyValue::Block:
      return FDE_CSSDisplay::Block;
    case FDE_CSSPropertyValue::None:
      return FDE_CSSDisplay::None;
    case FDE_CSSPropertyValue::ListItem:
      return FDE_CSSDisplay::ListItem;
    case FDE_CSSPropertyValue::InlineTable:
      return FDE_CSSDisplay::InlineTable;
    case FDE_CSSPropertyValue::InlineBlock:
      return FDE_CSSDisplay::InlineBlock;
    case FDE_CSSPropertyValue::Inline:
    default:
      return FDE_CSSDisplay::Inline;
  }
}

FDE_CSSTextAlign CFDE_CSSStyleSelector::ToTextAlign(
    FDE_CSSPropertyValue eValue) {
  switch (eValue) {
    case FDE_CSSPropertyValue::Center:
      return FDE_CSSTextAlign::Center;
    case FDE_CSSPropertyValue::Right:
      return FDE_CSSTextAlign::Right;
    case FDE_CSSPropertyValue::Justify:
      return FDE_CSSTextAlign::Justify;
    case FDE_CSSPropertyValue::Left:
    default:
      return FDE_CSSTextAlign::Left;
  }
}

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

FDE_CSSFontStyle CFDE_CSSStyleSelector::ToFontStyle(
    FDE_CSSPropertyValue eValue) {
  switch (eValue) {
    case FDE_CSSPropertyValue::Italic:
    case FDE_CSSPropertyValue::Oblique:
      return FDE_CSSFontStyle::Italic;
    default:
      return FDE_CSSFontStyle::Normal;
  }
}

bool CFDE_CSSStyleSelector::SetLengthWithPercent(
    FDE_CSSLength& width,
    FDE_CSSPrimitiveType eType,
    const CFX_RetainPtr<CFDE_CSSValue>& pValue,
    float fFontSize) {
  if (eType == FDE_CSSPrimitiveType::Number) {
    CFX_RetainPtr<CFDE_CSSNumberValue> v = pValue.As<CFDE_CSSNumberValue>();
    if (v->Kind() == FDE_CSSNumberType::Percent) {
      width.Set(FDE_CSSLengthUnit::Percent,
                pValue.As<CFDE_CSSNumberValue>()->Value() / 100.0f);
      return width.NonZero();
    }

    float fValue = v->Apply(fFontSize);
    width.Set(FDE_CSSLengthUnit::Point, fValue);
    return width.NonZero();
  } else if (eType == FDE_CSSPrimitiveType::Enum) {
    switch (pValue.As<CFDE_CSSEnumValue>()->Value()) {
      case FDE_CSSPropertyValue::Auto:
        width.Set(FDE_CSSLengthUnit::Auto);
        return true;
      case FDE_CSSPropertyValue::None:
        width.Set(FDE_CSSLengthUnit::None);
        return true;
      case FDE_CSSPropertyValue::Thin:
        width.Set(FDE_CSSLengthUnit::Point, 2);
        return true;
      case FDE_CSSPropertyValue::Medium:
        width.Set(FDE_CSSLengthUnit::Point, 3);
        return true;
      case FDE_CSSPropertyValue::Thick:
        width.Set(FDE_CSSLengthUnit::Point, 4);
        return true;
      default:
        return false;
    }
  }
  return false;
}

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

FDE_CSSVerticalAlign CFDE_CSSStyleSelector::ToVerticalAlign(
    FDE_CSSPropertyValue eValue) {
  switch (eValue) {
    case FDE_CSSPropertyValue::Middle:
      return FDE_CSSVerticalAlign::Middle;
    case FDE_CSSPropertyValue::Bottom:
      return FDE_CSSVerticalAlign::Bottom;
    case FDE_CSSPropertyValue::Super:
      return FDE_CSSVerticalAlign::Super;
    case FDE_CSSPropertyValue::Sub:
      return FDE_CSSVerticalAlign::Sub;
    case FDE_CSSPropertyValue::Top:
      return FDE_CSSVerticalAlign::Top;
    case FDE_CSSPropertyValue::TextTop:
      return FDE_CSSVerticalAlign::TextTop;
    case FDE_CSSPropertyValue::TextBottom:
      return FDE_CSSVerticalAlign::TextBottom;
    case FDE_CSSPropertyValue::Baseline:
    default:
      return FDE_CSSVerticalAlign::Baseline;
  }
}

uint32_t CFDE_CSSStyleSelector::ToTextDecoration(
    const CFX_RetainPtr<CFDE_CSSValueList>& pValue) {
  uint32_t dwDecoration = 0;
  for (int32_t i = pValue->CountValues() - 1; i >= 0; --i) {
    const CFX_RetainPtr<CFDE_CSSValue> pVal = pValue->GetValue(i);
    if (pVal->GetType() != FDE_CSSPrimitiveType::Enum)
      continue;

    switch (pVal.As<CFDE_CSSEnumValue>()->Value()) {
      case FDE_CSSPropertyValue::Underline:
        dwDecoration |= FDE_CSSTEXTDECORATION_Underline;
        break;
      case FDE_CSSPropertyValue::LineThrough:
        dwDecoration |= FDE_CSSTEXTDECORATION_LineThrough;
        break;
      case FDE_CSSPropertyValue::Overline:
        dwDecoration |= FDE_CSSTEXTDECORATION_Overline;
        break;
      case FDE_CSSPropertyValue::Blink:
        dwDecoration |= FDE_CSSTEXTDECORATION_Blink;
        break;
      case FDE_CSSPropertyValue::Double:
        dwDecoration |= FDE_CSSTEXTDECORATION_Double;
        break;
      default:
        break;
    }
  }
  return dwDecoration;
}

FDE_CSSFontVariant CFDE_CSSStyleSelector::ToFontVariant(
    FDE_CSSPropertyValue eValue) {
  return eValue == FDE_CSSPropertyValue::SmallCaps
             ? FDE_CSSFontVariant::SmallCaps
             : FDE_CSSFontVariant::Normal;
}
