// 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

#ifndef XFA_FDE_CSS_FDE_CSSSTYLESELECTOR_H_
#define XFA_FDE_CSS_FDE_CSSSTYLESELECTOR_H_

#include <vector>

#include "core/fxcrt/include/fx_ext.h"
#include "xfa/fde/css/fde_css.h"
#include "xfa/fde/css/fde_csscache.h"
#include "xfa/fde/css/fde_cssdeclaration.h"
#include "xfa/fgas/crt/fgas_memory.h"
#include "xfa/fgas/crt/fgas_system.h"

class CFDE_CSSAccelerator;
class CFDE_CSSComputedStyle;
class CXFA_CSSTagProvider;

class FDE_CSSRuleData : public CFX_Target {
 public:
  FDE_CSSRuleData(CFDE_CSSSelector* pSel,
                  CFDE_CSSDeclaration* pDecl,
                  uint32_t dwPos);

  CFDE_CSSSelector* pSelector;
  CFDE_CSSDeclaration* pDeclaration;
  uint32_t dwPriority;
  FDE_CSSRuleData* pNext;
};

class CFDE_CSSRuleCollection : public CFX_Target {
 public:
  CFDE_CSSRuleCollection()
      : m_pStaticStore(nullptr),
        m_pUniversalRules(nullptr),
        m_pPersudoRules(nullptr),
        m_iSelectors(0) {}
  ~CFDE_CSSRuleCollection() { Clear(); }

  void AddRulesFrom(const CFDE_CSSStyleSheetArray& sheets,
                    uint32_t dwMediaList,
                    IFGAS_FontMgr* pFontMgr);
  void Clear();

  int32_t CountSelectors() const { return m_iSelectors; }
  FDE_CSSRuleData* GetIDRuleData(uint32_t dwIDHash) {
    void* pData;
    return m_IDRules.Lookup((void*)(uintptr_t)dwIDHash, pData)
               ? (FDE_CSSRuleData*)pData
               : nullptr;
  }
  FDE_CSSRuleData* GetTagRuleData(uint32_t dwTagHasn) {
    void* pData;
    return m_TagRules.Lookup((void*)(uintptr_t)dwTagHasn, pData)
               ? (FDE_CSSRuleData*)pData
               : nullptr;
  }
  FDE_CSSRuleData* GetClassRuleData(uint32_t dwIDHash) {
    void* pData;
    return m_ClassRules.Lookup((void*)(uintptr_t)dwIDHash, pData)
               ? (FDE_CSSRuleData*)pData
               : nullptr;
  }
  FDE_CSSRuleData* GetUniversalRuleData() { return m_pUniversalRules; }
  FDE_CSSRuleData* GetPersudoRuleData() { return m_pPersudoRules; }

  IFX_MemoryAllocator* m_pStaticStore;

 protected:
  void AddRulesFrom(IFDE_CSSStyleSheet* pStyleSheet,
                    IFDE_CSSRule* pRule,
                    uint32_t dwMediaList,
                    IFGAS_FontMgr* pFontMgr);
  void AddRuleTo(CFX_MapPtrToPtr& map,
                 uint32_t dwKey,
                 CFDE_CSSSelector* pSel,
                 CFDE_CSSDeclaration* pDecl);
  FX_BOOL AddRuleTo(FDE_CSSRuleData*& pList, FDE_CSSRuleData* pData);
  FDE_CSSRuleData* NewRuleData(CFDE_CSSSelector* pSel,
                               CFDE_CSSDeclaration* pDecl);
  CFX_MapPtrToPtr m_IDRules;
  CFX_MapPtrToPtr m_TagRules;
  CFX_MapPtrToPtr m_ClassRules;
  FDE_CSSRuleData* m_pUniversalRules;
  FDE_CSSRuleData* m_pPersudoRules;
  int32_t m_iSelectors;
};

class CFDE_CSSStyleSelector : public CFX_Target {
 public:
  CFDE_CSSStyleSelector();
  ~CFDE_CSSStyleSelector() override;

  void SetFontMgr(IFGAS_FontMgr* pFontMgr);
  void SetDefFontSize(FX_FLOAT fFontSize);

  FX_BOOL SetStyleSheet(FDE_CSSSTYLESHEETGROUP eType,
                        IFDE_CSSStyleSheet* pSheet);
  FX_BOOL SetStyleSheets(FDE_CSSSTYLESHEETGROUP eType,
                         const CFDE_CSSStyleSheetArray* pArray);
  void SetStylePriority(FDE_CSSSTYLESHEETGROUP eType,
                        FDE_CSSSTYLESHEETPRIORITY ePriority);
  void UpdateStyleIndex(uint32_t dwMediaList);
  CFDE_CSSAccelerator* InitAccelerator();
  IFDE_CSSComputedStyle* CreateComputedStyle(
      IFDE_CSSComputedStyle* pParentStyle);
  int32_t MatchDeclarations(CXFA_CSSTagProvider* pTag,
                            CFDE_CSSDeclarationArray& matchedDecls,
                            FDE_CSSPERSUDO ePersudoType = FDE_CSSPERSUDO_NONE);
  void ComputeStyle(CXFA_CSSTagProvider* pTag,
                    const CFDE_CSSDeclaration** ppDeclArray,
                    int32_t iDeclCount,
                    IFDE_CSSComputedStyle* pDestStyle);

 protected:
  void Reset();
  void MatchRules(FDE_CSSTagCache* pCache,
                  FDE_CSSRuleData* pList,
                  FDE_CSSPERSUDO ePersudoType);
  FX_BOOL MatchSelector(FDE_CSSTagCache* pCache,
                        CFDE_CSSSelector* pSel,
                        FDE_CSSPERSUDO ePersudoType);
  void AppendInlineStyle(CFDE_CSSDeclaration* pDecl,
                         const FX_WCHAR* psz,
                         int32_t iLen);
  void ApplyDeclarations(FX_BOOL bPriority,
                         const CFDE_CSSDeclaration** ppDeclArray,
                         int32_t iDeclCount,
                         IFDE_CSSComputedStyle* pDestStyle);
  void ApplyProperty(FDE_CSSPROPERTY eProperty,
                     IFDE_CSSValue* pValue,
                     CFDE_CSSComputedStyle* pComputedStyle);

  FX_FLOAT ApplyNumber(FDE_CSSPRIMITIVETYPE eUnit,
                       FX_FLOAT fValue,
                       FX_FLOAT fPercentBase);
  FX_BOOL SetLengthWithPercent(FDE_CSSLENGTH& width,
                               FDE_CSSPRIMITIVETYPE eType,
                               IFDE_CSSPrimitiveValue* pPrimitive,
                               FX_FLOAT fFontSize);
  FX_FLOAT ToFontSize(FDE_CSSPROPERTYVALUE eValue, FX_FLOAT fCurFontSize);
  FDE_CSSDISPLAY ToDisplay(FDE_CSSPROPERTYVALUE eValue);
  FDE_CSSTEXTALIGN ToTextAlign(FDE_CSSPROPERTYVALUE eValue);
  uint16_t ToFontWeight(FDE_CSSPROPERTYVALUE eValue);
  FDE_CSSFONTSTYLE ToFontStyle(FDE_CSSPROPERTYVALUE eValue);
  FDE_CSSBORDERSTYLE ToBorderStyle(FDE_CSSPROPERTYVALUE eValue);
  FDE_CSSVERTICALALIGN ToVerticalAlign(FDE_CSSPROPERTYVALUE eValue);
  FDE_CSSLISTSTYLETYPE ToListStyleType(FDE_CSSPROPERTYVALUE eValue);
  FDE_CSSLISTSTYLEPOSITION ToListStylePosition(FDE_CSSPROPERTYVALUE eValue);
  FDE_CSSVISIBILITY ToVisibility(FDE_CSSPROPERTYVALUE eValue);
  FDE_CSSWHITESPACE ToWhiteSpace(FDE_CSSPROPERTYVALUE eValue);
  uint32_t ToTextDecoration(IFDE_CSSValueList* pList);
  FDE_CSSTEXTTRANSFORM ToTextTransform(FDE_CSSPROPERTYVALUE eValue);
  FDE_CSSFONTVARIANT ToFontVariant(FDE_CSSPROPERTYVALUE eValue);
  FDE_CSSFLOAT ToFloat(FDE_CSSPROPERTYVALUE eValue);
  FDE_CSSCLEAR ToClear(FDE_CSSPROPERTYVALUE eValue);
  FDE_CSSWRITINGMODE ToWritingMode(FDE_CSSPROPERTYVALUE eValue);
  FDE_CSSWORDBREAK ToWordBreak(FDE_CSSPROPERTYVALUE eValue);
  FDE_CSSPAGEBREAK ToPageBreak(FDE_CSSPROPERTYVALUE eValue);
  FDE_CSSOVERFLOW ToOverflow(FDE_CSSPROPERTYVALUE eValue);
  FDE_CSSLINEBREAK ToLineBreak(FDE_CSSPROPERTYVALUE eValue);
  FDE_CSSTEXTCOMBINE ToTextCombine(FDE_CSSPROPERTYVALUE eValue);
  FX_BOOL ToTextEmphasisMark(FDE_CSSPROPERTYVALUE eValue,
                             FDE_CSSTEXTEMPHASISMARK& eMark);
  FX_BOOL ToTextEmphasisFill(FDE_CSSPROPERTYVALUE eValue,
                             FDE_CSSTEXTEMPHASISFILL& eFill);
  FDE_CSSCURSOR ToCursor(FDE_CSSPROPERTYVALUE eValue);
  FDE_CSSPOSITION ToPosition(FDE_CSSPROPERTYVALUE eValue);
  FDE_CSSCAPTIONSIDE ToCaptionSide(FDE_CSSPROPERTYVALUE eValue);
  FDE_CSSBKGREPEAT ToBKGRepeat(FDE_CSSPROPERTYVALUE eValue);
  FDE_CSSBKGATTACHMENT ToBKGAttachment(FDE_CSSPROPERTYVALUE eValue);
  FDE_CSSRUBYALIGN ToRubyAlign(FDE_CSSPROPERTYVALUE eValue);
  FDE_CSSRUBYOVERHANG ToRubyOverhang(FDE_CSSPROPERTYVALUE eValue);
  FDE_CSSRUBYPOSITION ToRubyPosition(FDE_CSSPROPERTYVALUE eValue);
  FDE_CSSRUBYSPAN ToRubySpan(FDE_CSSPROPERTYVALUE eValue);

  IFGAS_FontMgr* m_pFontMgr;
  FX_FLOAT m_fDefFontSize;
  IFX_MemoryAllocator* m_pRuleDataStore;
  CFDE_CSSStyleSheetArray m_SheetGroups[FDE_CSSSTYLESHEETGROUP_MAX];
  CFDE_CSSRuleCollection m_RuleCollection[FDE_CSSSTYLESHEETGROUP_MAX];
  FDE_CSSSTYLESHEETGROUP m_ePriorities[FDE_CSSSTYLESHEETPRIORITY_MAX];
  IFX_MemoryAllocator* m_pInlineStyleStore;
  IFX_MemoryAllocator* m_pFixedStyleStore;
  CFDE_CSSAccelerator* m_pAccelerator;
  std::vector<FDE_CSSRuleData*> m_MatchedRules;
};

struct FDE_CSSCOUNTERDATA {
 public:
  FDE_CSSCOUNTERDATA() { FXSYS_memset(this, 0, sizeof(FDE_CSSCOUNTERDATA)); }
  FX_BOOL GetCounterIncrement(int32_t& iValue) {
    iValue = m_iIncVal;
    return m_bIncrement;
  }
  FX_BOOL GetCounterReset(int32_t& iValue) {
    iValue = m_iResetVal;
    return m_bReset;
  }

  const FX_WCHAR* m_pszIdent;
  FX_BOOL m_bIncrement;
  FX_BOOL m_bReset;
  int32_t m_iIncVal;
  int32_t m_iResetVal;
};

class CFDE_CSSCounterStyle {
 public:
  CFDE_CSSCounterStyle() : m_pCounterInc(nullptr), m_pCounterReset(nullptr) {}

  void SetCounterIncrementList(IFDE_CSSValueList* pList) {
    m_pCounterInc = pList;
    m_bIndexDirty = TRUE;
  }

  void SetCounterResetList(IFDE_CSSValueList* pList) {
    m_pCounterReset = pList;
    m_bIndexDirty = TRUE;
  }

  int32_t CountCounters() {
    UpdateIndex();
    return m_arrCounterData.GetSize();
  }

  FX_BOOL GetCounterIncrement(int32_t index, int32_t& iValue) {
    UpdateIndex();
    return m_arrCounterData.ElementAt(index).GetCounterIncrement(iValue);
  }

  FX_BOOL GetCounterReset(int32_t index, int32_t& iValue) {
    UpdateIndex();
    return m_arrCounterData.ElementAt(index).GetCounterReset(iValue);
  }

  const FX_WCHAR* GetCounterIdentifier(int32_t index) {
    UpdateIndex();
    return m_arrCounterData.ElementAt(index).m_pszIdent;
  }

 protected:
  void UpdateIndex();
  void DoUpdateIndex(IFDE_CSSValueList* pList);
  int32_t FindIndex(const FX_WCHAR* pszIdentifier);

  IFDE_CSSValueList* m_pCounterInc;
  IFDE_CSSValueList* m_pCounterReset;
  CFX_ArrayTemplate<FDE_CSSCOUNTERDATA> m_arrCounterData;
  FX_BOOL m_bIndexDirty;
};

class CFDE_CSSInheritedData {
 public:
  void Reset() {
    FXSYS_memset(this, 0, sizeof(CFDE_CSSInheritedData));
    m_LetterSpacing.Set(FDE_CSSLENGTHUNIT_Normal);
    m_WordSpacing.Set(FDE_CSSLENGTHUNIT_Normal);
    m_TextIndent.Set(FDE_CSSLENGTHUNIT_Point, 0);
    m_fFontSize = 12.0f;
    m_fLineHeight = 14.0f;
    m_wFontWeight = 400;
    m_dwFontColor = 0xFF000000;
    m_iWidows = 2;
    m_bTextEmphasisColorCurrent = TRUE;
    m_iOrphans = 2;
  }

  const FX_WCHAR* m_pszListStyleImage;
  FDE_CSSLENGTH m_LetterSpacing;
  FDE_CSSLENGTH m_WordSpacing;
  FDE_CSSLENGTH m_TextIndent;
  IFDE_CSSValueList* m_pFontFamily;
  IFDE_CSSValueList* m_pQuotes;
  IFDE_CSSValueList* m_pCursorUris;
  FDE_CSSCURSOR m_eCursor;
  FX_FLOAT m_fFontSize;
  FX_FLOAT m_fLineHeight;
  FX_ARGB m_dwFontColor;
  FX_ARGB m_dwTextEmphasisColor;
  uint16_t m_wFontWeight;
  int32_t m_iWidows;
  int32_t m_iOrphans;
  const FX_WCHAR* m_pszTextEmphasisCustomMark;
  uint32_t m_eFontVariant : 1;
  uint32_t m_eFontStyle : 1;
  uint32_t m_bTextEmphasisColorCurrent : 1;
  uint32_t m_eTextAligh : 2;
  uint32_t m_eVisibility : 2;
  uint32_t m_eWhiteSpace : 3;
  uint32_t m_eTextTransform : 2;
  uint32_t m_eWritingMode : 2;
  uint32_t m_eWordBreak : 2;
  uint32_t m_eLineBreak : 2;
  uint32_t m_eTextEmphasisFill : 1;
  uint32_t m_eTextEmphasisMark : 3;
  uint32_t m_eCaptionSide : 3;
  uint8_t m_eRubyAlign : 4;
  uint8_t m_eRubyOverhang : 2;
  uint8_t m_eRubyPosition : 2;
};

class CFDE_CSSNonInheritedData {
 public:
  void Reset() {
    FXSYS_memset(this, 0, sizeof(CFDE_CSSNonInheritedData));
    m_MarginWidth = m_BorderWidth =
        m_PaddingWidth.Set(FDE_CSSLENGTHUNIT_Point, 0);
    m_MinBoxSize.Set(FDE_CSSLENGTHUNIT_Point, 0);
    m_MaxBoxSize.Set(FDE_CSSLENGTHUNIT_None);
    m_eDisplay = FDE_CSSDISPLAY_Inline;
    m_fVerticalAlign = 0.0f;
    m_ColumnCount.Set(FDE_CSSLENGTHUNIT_Auto);
    m_ColumnGap.Set(FDE_CSSLENGTHUNIT_Normal);
    m_bColumnRuleColorSame = TRUE;
    m_ColumnWidth.Set(FDE_CSSLENGTHUNIT_Auto);
    m_ColumnRuleWidth.Set(FDE_CSSLENGTHUNIT_Auto);
    m_eTextCombine = FDE_CSSTEXTCOMBINE_None;
  }

  IFDE_CSSValueList* m_pContentList;
  CFDE_CSSCounterStyle* m_pCounterStyle;
  FDE_CSSRECT m_MarginWidth;
  FDE_CSSRECT m_BorderWidth;
  FDE_CSSRECT m_PaddingWidth;
  FDE_CSSSIZE m_BoxSize;
  FDE_CSSSIZE m_MinBoxSize;
  FDE_CSSSIZE m_MaxBoxSize;
  FDE_CSSPOINT m_BKGPosition;
  const FX_WCHAR* m_pszBKGImage;
  FX_ARGB m_dwBKGColor;
  FX_ARGB m_dwBDRLeftColor;
  FX_ARGB m_dwBDRTopColor;
  FX_ARGB m_dwBDRRightColor;
  FX_ARGB m_dwBDRBottomColor;
  IFDE_CSSValue* m_pRubySpan;
  FDE_CSSLENGTH m_ColumnCount;
  FDE_CSSLENGTH m_ColumnGap;
  FDE_CSSLENGTH m_ColumnRuleWidth;
  FDE_CSSLENGTH m_ColumnWidth;
  FX_ARGB m_dwColumnRuleColor;
  FDE_CSSLENGTH m_Top;
  FDE_CSSLENGTH m_Bottom;
  FDE_CSSLENGTH m_Left;
  FDE_CSSLENGTH m_Right;

  FX_FLOAT m_fVerticalAlign;
  FX_FLOAT m_fTextCombineNumber;
  uint32_t m_eBDRLeftStyle : 4;
  uint32_t m_eBDRTopStyle : 4;
  uint32_t m_eBDRRightStyle : 4;
  uint32_t m_eBDRBottomStyle : 4;
  uint32_t m_eDisplay : 5;
  uint32_t m_eVerticalAlign : 4;
  uint32_t m_eListStyleType : 5;
  uint32_t m_eColumnRuleStyle : 4;
  uint32_t m_ePageBreakInside : 3;
  uint32_t m_ePageBreakAfter : 3;
  uint32_t m_ePageBreakBefore : 3;
  uint32_t m_ePosition : 2;
  uint32_t m_eBKGRepeat : 2;
  uint32_t m_eFloat : 2;
  uint32_t m_eClear : 2;
  uint32_t m_eOverflowX : 3;
  uint32_t m_eOverflowY : 3;
  uint32_t m_eListStylePosition : 1;
  uint32_t m_eBKGAttachment : 1;
  uint32_t m_bHasMargin : 1;
  uint32_t m_bHasBorder : 1;
  uint32_t m_bHasPadding : 1;
  uint32_t m_dwTextDecoration : 5;
  uint32_t m_eTextCombine : 1;
  uint32_t m_bColumnRuleColorSame : 1;
  uint32_t m_bHasTextCombineNumber : 1;
};

class CFDE_CSSComputedStyle : public IFDE_CSSComputedStyle,
                              public IFDE_CSSBoundaryStyle,
                              public IFDE_CSSFontStyle,
                              public IFDE_CSSPositionStyle,
                              public IFDE_CSSParagraphStyle,
                              public CFX_Target {
 public:
  CFDE_CSSComputedStyle(IFX_MemoryAllocator* pAlloc)
      : m_dwRefCount(1), m_pAllocator(pAlloc) {}

  ~CFDE_CSSComputedStyle() override {}

  // IFX_Retainable:
  uint32_t Retain() override { return ++m_dwRefCount; }
  uint32_t Release() override {
    uint32_t dwRefCount = --m_dwRefCount;
    if (dwRefCount == 0) {
      delete m_NonInheritedData.m_pCounterStyle;
      FXTARGET_DeleteWith(CFDE_CSSComputedStyle, m_pAllocator, this);
    }
    return dwRefCount;
  }

  // IFDE_CSSComputedStyle:
  void Reset() override {
    m_InheritedData.Reset();
    m_NonInheritedData.Reset();
  }

  IFDE_CSSFontStyle* GetFontStyles() override {
    return static_cast<IFDE_CSSFontStyle*>(this);
  }

  IFDE_CSSBoundaryStyle* GetBoundaryStyles() override {
    return static_cast<IFDE_CSSBoundaryStyle*>(this);
  }

  IFDE_CSSPositionStyle* GetPositionStyles() override {
    return static_cast<IFDE_CSSPositionStyle*>(this);
  }

  IFDE_CSSParagraphStyle* GetParagraphStyles() override {
    return static_cast<IFDE_CSSParagraphStyle*>(this);
  }

  FX_BOOL GetCustomStyle(const CFX_WideStringC& wsName,
                         CFX_WideString& wsValue) const override {
    for (int32_t i = m_CustomProperties.GetSize() - 2; i > -1; i -= 2) {
      if (wsName == m_CustomProperties[i]) {
        wsValue = m_CustomProperties[i + 1];
        return TRUE;
      }
    }
    return FALSE;
  }

  // IFDE_CSSFontStyle:
  int32_t CountFontFamilies() const override {
    return m_InheritedData.m_pFontFamily
               ? m_InheritedData.m_pFontFamily->CountValues()
               : 0;
  }

  const FX_WCHAR* GetFontFamily(int32_t index) const override {
    return (static_cast<IFDE_CSSPrimitiveValue*>(
                m_InheritedData.m_pFontFamily->GetValue(index)))
        ->GetString(index);
  }

  uint16_t GetFontWeight() const override {
    return m_InheritedData.m_wFontWeight;
  }

  FDE_CSSFONTVARIANT GetFontVariant() const override {
    return static_cast<FDE_CSSFONTVARIANT>(m_InheritedData.m_eFontVariant);
  }

  FDE_CSSFONTSTYLE GetFontStyle() const override {
    return static_cast<FDE_CSSFONTSTYLE>(m_InheritedData.m_eFontStyle);
  }

  FX_FLOAT GetFontSize() const override { return m_InheritedData.m_fFontSize; }

  FX_ARGB GetColor() const override { return m_InheritedData.m_dwFontColor; }

  void SetFontWeight(uint16_t wFontWeight) override {
    m_InheritedData.m_wFontWeight = wFontWeight;
  }

  void SetFontVariant(FDE_CSSFONTVARIANT eFontVariant) override {
    m_InheritedData.m_eFontVariant = eFontVariant;
  }

  void SetFontStyle(FDE_CSSFONTSTYLE eFontStyle) override {
    m_InheritedData.m_eFontStyle = eFontStyle;
  }

  void SetFontSize(FX_FLOAT fFontSize) override {
    m_InheritedData.m_fFontSize = fFontSize;
  }

  void SetColor(FX_ARGB dwFontColor) override {
    m_InheritedData.m_dwFontColor = dwFontColor;
  }

  // IFDE_CSSBoundaryStyle:
  const FDE_CSSRECT* GetBorderWidth() const override {
    return m_NonInheritedData.m_bHasBorder ? &(m_NonInheritedData.m_BorderWidth)
                                           : nullptr;
  }

  const FDE_CSSRECT* GetMarginWidth() const override {
    return m_NonInheritedData.m_bHasMargin ? &(m_NonInheritedData.m_MarginWidth)
                                           : nullptr;
  }

  const FDE_CSSRECT* GetPaddingWidth() const override {
    return m_NonInheritedData.m_bHasPadding
               ? &(m_NonInheritedData.m_PaddingWidth)
               : nullptr;
  }

  void SetMarginWidth(const FDE_CSSRECT& rect) override {
    m_NonInheritedData.m_MarginWidth = rect;
    m_NonInheritedData.m_bHasMargin = TRUE;
  }

  void SetPaddingWidth(const FDE_CSSRECT& rect) override {
    m_NonInheritedData.m_PaddingWidth = rect;
    m_NonInheritedData.m_bHasPadding = TRUE;
  }

  // IFDE_CSSPositionStyle:
  FDE_CSSDISPLAY GetDisplay() const override {
    return static_cast<FDE_CSSDISPLAY>(m_NonInheritedData.m_eDisplay);
  }

  // IFDE_CSSParagraphStyle:
  FX_FLOAT GetLineHeight() const override {
    return m_InheritedData.m_fLineHeight;
  }

  const FDE_CSSLENGTH& GetTextIndent() const override {
    return m_InheritedData.m_TextIndent;
  }

  FDE_CSSTEXTALIGN GetTextAlign() const override {
    return static_cast<FDE_CSSTEXTALIGN>(m_InheritedData.m_eTextAligh);
  }

  FDE_CSSVERTICALALIGN GetVerticalAlign() const override {
    return static_cast<FDE_CSSVERTICALALIGN>(
        m_NonInheritedData.m_eVerticalAlign);
  }

  FX_FLOAT GetNumberVerticalAlign() const override {
    return m_NonInheritedData.m_fVerticalAlign;
  }

  uint32_t GetTextDecoration() const override {
    return m_NonInheritedData.m_dwTextDecoration;
  }

  const FDE_CSSLENGTH& GetLetterSpacing() const override {
    return m_InheritedData.m_LetterSpacing;
  }

  void SetLineHeight(FX_FLOAT fLineHeight) override {
    m_InheritedData.m_fLineHeight = fLineHeight;
  }

  void SetTextIndent(const FDE_CSSLENGTH& textIndent) override {
    m_InheritedData.m_TextIndent = textIndent;
  }

  void SetTextAlign(FDE_CSSTEXTALIGN eTextAlign) override {
    m_InheritedData.m_eTextAligh = eTextAlign;
  }

  void SetNumberVerticalAlign(FX_FLOAT fAlign) override {
    m_NonInheritedData.m_eVerticalAlign = FDE_CSSVERTICALALIGN_Number,
    m_NonInheritedData.m_fVerticalAlign = fAlign;
  }

  void SetTextDecoration(uint32_t dwTextDecoration) override {
    m_NonInheritedData.m_dwTextDecoration = dwTextDecoration;
  }

  void SetLetterSpacing(const FDE_CSSLENGTH& letterSpacing) override {
    m_InheritedData.m_LetterSpacing = letterSpacing;
  }

  void AddCustomStyle(const CFX_WideString& wsName,
                      const CFX_WideString& wsValue) {
    m_CustomProperties.Add(wsName);
    m_CustomProperties.Add(wsValue);
  }

  uint32_t m_dwRefCount;
  IFX_MemoryAllocator* m_pAllocator;
  CFDE_CSSInheritedData m_InheritedData;
  CFDE_CSSNonInheritedData m_NonInheritedData;
  CFX_WideStringArray m_CustomProperties;
};

#endif  // XFA_FDE_CSS_FDE_CSSSTYLESELECTOR_H_
