Home | History | Annotate | Download | only in css
      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/src/foxitlib.h"
      8 #include "fde_csscache.h"
      9 #include "fde_cssdeclaration.h"
     10 #include "fde_cssstyleselector.h"
     11 int32_t CFDE_CSSCounterStyle::FindIndex(const FX_WCHAR* pszIdentifier) {
     12   int32_t iCount = m_arrCounterData.GetSize();
     13   for (int32_t i = 0; i < iCount; i++) {
     14     if (FXSYS_wcscmp(pszIdentifier, m_arrCounterData.ElementAt(i).m_pszIdent) ==
     15         0) {
     16       return i;
     17     }
     18   }
     19   return -1;
     20 }
     21 void CFDE_CSSCounterStyle::DoUpdateIndex(IFDE_CSSValueList* pList) {
     22   if (pList == NULL) {
     23     return;
     24   }
     25   int32_t iCount = pList->CountValues();
     26   FX_FLOAT fDefValue = 1.0;
     27   FX_BOOL bDefIncrement = TRUE;
     28   if (pList == m_pCounterReset) {
     29     fDefValue = 0.0;
     30     bDefIncrement = FALSE;
     31   }
     32   for (int32_t i = 0; i < iCount; i++) {
     33     IFDE_CSSValueList* pCounter = (IFDE_CSSValueList*)pList->GetValue(i);
     34     int32_t iLen;
     35     const FX_WCHAR* pszIdentifier =
     36         ((IFDE_CSSPrimitiveValue*)(pCounter->GetValue(0)))->GetString(iLen);
     37     FX_FLOAT fValue = fDefValue;
     38     if (pCounter->CountValues() > 1) {
     39       fValue = ((IFDE_CSSPrimitiveValue*)(pCounter->GetValue(1)))->GetFloat();
     40     }
     41     int32_t iIndex = FindIndex(pszIdentifier);
     42     if (iIndex == -1) {
     43       FDE_CSSCOUNTERDATA data;
     44       data.m_pszIdent = pszIdentifier;
     45       if (bDefIncrement) {
     46         data.m_bIncrement = TRUE;
     47         data.m_iIncVal = (int32_t)fValue;
     48       } else {
     49         data.m_iResetVal = (int32_t)fValue;
     50         data.m_bReset = TRUE;
     51       }
     52       m_arrCounterData.Add(data);
     53     } else {
     54       FDE_CSSCOUNTERDATA& data = m_arrCounterData.ElementAt(iIndex);
     55       if (bDefIncrement) {
     56         data.m_bIncrement = TRUE;
     57         data.m_iIncVal += (int32_t)fValue;
     58       } else {
     59         data.m_bReset = TRUE;
     60         data.m_iResetVal = (int32_t)fValue;
     61       }
     62     }
     63   }
     64 }
     65 void CFDE_CSSCounterStyle::UpdateIndex() {
     66   if (!m_bIndexDirty) {
     67     return;
     68   }
     69   m_arrCounterData.RemoveAll();
     70   DoUpdateIndex(m_pCounterInc);
     71   DoUpdateIndex(m_pCounterReset);
     72   m_bIndexDirty = FALSE;
     73 }
     74 FDE_CSSTEXTEMPHASISMARK CFDE_CSSComputedStyle::GetTextEmphasisMark() const {
     75   if (m_InheritedData.m_eTextEmphasisMark != FDE_CSSTEXTEMPHASISMARK_Auto) {
     76     return (FDE_CSSTEXTEMPHASISMARK)m_InheritedData.m_eTextEmphasisMark;
     77   }
     78   if (m_InheritedData.m_eWritingMode == FDE_CSSWRITINGMODE_HorizontalTb) {
     79     return FDE_CSSTEXTEMPHASISMARK_Dot;
     80   }
     81   return FDE_CSSTEXTEMPHASISMARK_Sesame;
     82 }
     83 _FDE_CSSRULEDATA::_FDE_CSSRULEDATA(IFDE_CSSSelector* pSel,
     84                                    IFDE_CSSDeclaration* pDecl,
     85                                    FX_DWORD dwPos)
     86     : pSelector(pSel), pDeclaration(pDecl), dwPriority(dwPos), pNext(NULL) {
     87   static const FX_DWORD s_Specific[5] = {0x00010000, 0x00010000, 0x00100000,
     88                                          0x00100000, 0x01000000};
     89   for (; pSel != NULL; pSel = pSel->GetNextSelector()) {
     90     FDE_CSSSELECTORTYPE eType = pSel->GetType();
     91     if (eType > FDE_CSSSELECTORTYPE_Descendant ||
     92         pSel->GetNameHash() != FDE_CSSUNIVERSALHASH) {
     93       dwPriority += s_Specific[eType];
     94     }
     95   }
     96 }
     97 void CFDE_CSSRuleCollection::Clear() {
     98   m_IDRules.RemoveAll();
     99   m_TagRules.RemoveAll();
    100   m_ClassRules.RemoveAll();
    101   m_pUniversalRules = NULL;
    102   m_pStaticStore = NULL;
    103   m_iSelectors = 0;
    104 }
    105 void CFDE_CSSRuleCollection::AddRulesFrom(const CFDE_CSSStyleSheetArray& sheets,
    106                                           FX_DWORD dwMediaList,
    107                                           IFX_FontMgr* pFontMgr) {
    108   int32_t iSheets = sheets.GetSize();
    109   for (int32_t i = 0; i < iSheets; ++i) {
    110     IFDE_CSSStyleSheet* pSheet = sheets.GetAt(i);
    111     if (FX_DWORD dwMatchMedia = pSheet->GetMediaList() & dwMediaList) {
    112       int32_t iRules = pSheet->CountRules();
    113       for (int32_t j = 0; j < iRules; j++) {
    114         AddRulesFrom(pSheet, pSheet->GetRule(j), dwMatchMedia, pFontMgr);
    115       }
    116     }
    117   }
    118 }
    119 void CFDE_CSSRuleCollection::AddRulesFrom(IFDE_CSSStyleSheet* pStyleSheet,
    120                                           IFDE_CSSRule* pRule,
    121                                           FX_DWORD dwMediaList,
    122                                           IFX_FontMgr* pFontMgr) {
    123   switch (pRule->GetType()) {
    124     case FDE_CSSRULETYPE_Style: {
    125       IFDE_CSSStyleRule* pStyleRule = (IFDE_CSSStyleRule*)pRule;
    126       IFDE_CSSDeclaration* pDeclaration = pStyleRule->GetDeclaration();
    127       int32_t iSelectors = pStyleRule->CountSelectorLists();
    128       for (int32_t i = 0; i < iSelectors; ++i) {
    129         IFDE_CSSSelector* pSelector = pStyleRule->GetSelectorList(i);
    130         if (pSelector->GetType() == FDE_CSSSELECTORTYPE_Persudo) {
    131           FDE_LPCSSRULEDATA pData = NewRuleData(pSelector, pDeclaration);
    132           AddRuleTo(m_pPersudoRules, pData);
    133           continue;
    134         }
    135         if (pSelector->GetNameHash() != FDE_CSSUNIVERSALHASH) {
    136           AddRuleTo(m_TagRules, pSelector->GetNameHash(), pSelector,
    137                     pDeclaration);
    138           continue;
    139         }
    140         IFDE_CSSSelector* pNext = pSelector->GetNextSelector();
    141         if (pNext == NULL) {
    142           FDE_LPCSSRULEDATA pData = NewRuleData(pSelector, pDeclaration);
    143           AddRuleTo(m_pUniversalRules, pData);
    144           continue;
    145         }
    146         switch (pNext->GetType()) {
    147           case FDE_CSSSELECTORTYPE_ID:
    148             AddRuleTo(m_IDRules, pNext->GetNameHash(), pSelector, pDeclaration);
    149             break;
    150           case FDE_CSSSELECTORTYPE_Class:
    151             AddRuleTo(m_ClassRules, pNext->GetNameHash(), pSelector,
    152                       pDeclaration);
    153             break;
    154           case FDE_CSSSELECTORTYPE_Descendant:
    155           case FDE_CSSSELECTORTYPE_Element:
    156             AddRuleTo(m_pUniversalRules, NewRuleData(pSelector, pDeclaration));
    157             break;
    158           default:
    159             FXSYS_assert(FALSE);
    160             break;
    161         }
    162       }
    163     } break;
    164     case FDE_CSSRULETYPE_Media: {
    165       IFDE_CSSMediaRule* pMediaRule = (IFDE_CSSMediaRule*)pRule;
    166       if (pMediaRule->GetMediaList() & dwMediaList) {
    167         int32_t iRules = pMediaRule->CountRules();
    168         for (int32_t i = 0; i < iRules; ++i) {
    169           AddRulesFrom(pStyleSheet, pMediaRule->GetRule(i), dwMediaList,
    170                        pFontMgr);
    171         }
    172       }
    173     } break;
    174     default:
    175       break;
    176   }
    177 }
    178 void CFDE_CSSRuleCollection::AddRuleTo(CFX_MapPtrToPtr& map,
    179                                        FX_DWORD dwKey,
    180                                        IFDE_CSSSelector* pSel,
    181                                        IFDE_CSSDeclaration* pDecl) {
    182   void* pKey = (void*)(uintptr_t)dwKey;
    183   FDE_LPCSSRULEDATA pData = NewRuleData(pSel, pDecl);
    184   FDE_LPCSSRULEDATA pList = NULL;
    185   if (!map.Lookup(pKey, (void*&)pList)) {
    186     map.SetAt(pKey, pData);
    187   } else if (AddRuleTo(pList, pData)) {
    188     map.SetAt(pKey, pList);
    189   }
    190 }
    191 inline FX_BOOL CFDE_CSSRuleCollection::AddRuleTo(FDE_LPCSSRULEDATA& pList,
    192                                                  FDE_LPCSSRULEDATA pData) {
    193   if (pList == NULL) {
    194     pList = pData;
    195     return TRUE;
    196   } else {
    197     pData->pNext = pList->pNext;
    198     pList->pNext = pData;
    199     return FALSE;
    200   }
    201 }
    202 inline FDE_LPCSSRULEDATA CFDE_CSSRuleCollection::NewRuleData(
    203     IFDE_CSSSelector* pSel,
    204     IFDE_CSSDeclaration* pDecl) {
    205   return FDE_NewWith(m_pStaticStore)
    206       FDE_CSSRULEDATA(pSel, pDecl, ++m_iSelectors);
    207 }
    208 IFDE_CSSStyleSelector* IFDE_CSSStyleSelector::Create() {
    209   return new CFDE_CSSStyleSelector;
    210 }
    211 CFDE_CSSStyleSelector::CFDE_CSSStyleSelector()
    212     : m_pFontMgr(NULL),
    213       m_fDefFontSize(12.0f),
    214       m_pRuleDataStore(NULL),
    215       m_pInlineStyleStore(NULL),
    216       m_pFixedStyleStore(NULL),
    217       m_pAccelerator(NULL) {
    218   m_ePriorities[FDE_CSSSTYLESHEETPRIORITY_High] = FDE_CSSSTYLESHEETGROUP_Author;
    219   m_ePriorities[FDE_CSSSTYLESHEETPRIORITY_Mid] = FDE_CSSSTYLESHEETGROUP_User;
    220   m_ePriorities[FDE_CSSSTYLESHEETPRIORITY_Low] =
    221       FDE_CSSSTYLESHEETGROUP_UserAgent;
    222 }
    223 CFDE_CSSStyleSelector::~CFDE_CSSStyleSelector() {
    224   Reset();
    225   if (m_pInlineStyleStore != NULL) {
    226     m_pInlineStyleStore->Release();
    227   }
    228   if (m_pFixedStyleStore != NULL) {
    229     m_pFixedStyleStore->Release();
    230   }
    231   if (m_pAccelerator != NULL) {
    232     delete m_pAccelerator;
    233   }
    234 }
    235 void CFDE_CSSStyleSelector::SetFontMgr(IFX_FontMgr* pFontMgr) {
    236   m_pFontMgr = pFontMgr;
    237 }
    238 void CFDE_CSSStyleSelector::SetDefFontSize(FX_FLOAT fFontSize) {
    239   FXSYS_assert(fFontSize > 0);
    240   m_fDefFontSize = fFontSize;
    241 }
    242 IFDE_CSSAccelerator* CFDE_CSSStyleSelector::InitAccelerator() {
    243   if (m_pAccelerator == NULL) {
    244     m_pAccelerator = new CFDE_CSSAccelerator;
    245     FXSYS_assert(m_pAccelerator != NULL);
    246   }
    247   m_pAccelerator->Clear();
    248   return m_pAccelerator;
    249 }
    250 IFDE_CSSComputedStyle* CFDE_CSSStyleSelector::CreateComputedStyle(
    251     IFDE_CSSComputedStyle* pParentStyle) {
    252   if (m_pFixedStyleStore == NULL) {
    253     m_pFixedStyleStore = FX_CreateAllocator(FX_ALLOCTYPE_Fixed, 16,
    254                                             sizeof(CFDE_CSSComputedStyle));
    255     FXSYS_assert(m_pFixedStyleStore != NULL);
    256   }
    257   CFDE_CSSComputedStyle* pStyle =
    258       FDE_NewWith(m_pFixedStyleStore) CFDE_CSSComputedStyle(m_pFixedStyleStore);
    259   if (pParentStyle) {
    260     pStyle->m_InheritedData =
    261         ((CFDE_CSSComputedStyle*)pParentStyle)->m_InheritedData;
    262   } else {
    263     pStyle->m_InheritedData.Reset();
    264   }
    265   pStyle->m_NonInheritedData.Reset();
    266   return pStyle;
    267 }
    268 FX_BOOL CFDE_CSSStyleSelector::SetStyleSheet(FDE_CSSSTYLESHEETGROUP eType,
    269                                              IFDE_CSSStyleSheet* pSheet) {
    270   FXSYS_assert(eType < FDE_CSSSTYLESHEETGROUP_MAX);
    271   CFDE_CSSStyleSheetArray& dest = m_SheetGroups[eType];
    272   dest.RemoveAt(0, dest.GetSize());
    273   if (pSheet != NULL) {
    274     dest.Add(pSheet);
    275   }
    276   return TRUE;
    277 }
    278 FX_BOOL CFDE_CSSStyleSelector::SetStyleSheets(
    279     FDE_CSSSTYLESHEETGROUP eType,
    280     const CFDE_CSSStyleSheetArray* pArray) {
    281   FXSYS_assert(eType < FDE_CSSSTYLESHEETGROUP_MAX);
    282   CFDE_CSSStyleSheetArray& dest = m_SheetGroups[eType];
    283   if (pArray == NULL) {
    284     dest.RemoveAt(0, dest.GetSize());
    285   } else {
    286     dest.Copy(*pArray);
    287   }
    288   return TRUE;
    289 }
    290 void CFDE_CSSStyleSelector::SetStylePriority(
    291     FDE_CSSSTYLESHEETGROUP eType,
    292     FDE_CSSSTYLESHEETPRIORITY ePriority) {
    293   m_ePriorities[ePriority] = eType;
    294 }
    295 void CFDE_CSSStyleSelector::UpdateStyleIndex(FX_DWORD dwMediaList) {
    296   Reset();
    297   m_pRuleDataStore = FX_CreateAllocator(FX_ALLOCTYPE_Static, 1024, 0);
    298   FXSYS_assert(m_pRuleDataStore != NULL);
    299   for (int32_t iGroup = 0; iGroup < FDE_CSSSTYLESHEETGROUP_MAX; ++iGroup) {
    300     CFDE_CSSRuleCollection& rules = m_RuleCollection[iGroup];
    301     rules.m_pStaticStore = m_pRuleDataStore;
    302     rules.AddRulesFrom(m_SheetGroups[iGroup], dwMediaList, m_pFontMgr);
    303   }
    304 }
    305 void CFDE_CSSStyleSelector::Reset() {
    306   for (int32_t iGroup = 0; iGroup < FDE_CSSSTYLESHEETGROUP_MAX; ++iGroup) {
    307     m_RuleCollection[iGroup].Clear();
    308   }
    309   if (m_pRuleDataStore != NULL) {
    310     m_pRuleDataStore->Release();
    311     m_pRuleDataStore = NULL;
    312   }
    313 }
    314 int32_t CFDE_CSSStyleSelector::MatchDeclarations(
    315     IFDE_CSSTagProvider* pTag,
    316     CFDE_CSSDeclarationArray& matchedDecls,
    317     FDE_CSSPERSUDO ePersudoType) {
    318   FXSYS_assert(m_pAccelerator != NULL && pTag != NULL);
    319   FDE_LPCSSTAGCACHE pCache = m_pAccelerator->GetTopElement();
    320   FXSYS_assert(pCache != NULL && pCache->GetTag() == pTag);
    321   matchedDecls.RemoveAt(0, matchedDecls.GetSize());
    322   for (int32_t ePriority = FDE_CSSSTYLESHEETPRIORITY_MAX - 1; ePriority >= 0;
    323        --ePriority) {
    324     FDE_CSSSTYLESHEETGROUP eGroup = m_ePriorities[ePriority];
    325     CFDE_CSSRuleCollection& rules = m_RuleCollection[eGroup];
    326     if (rules.CountSelectors() == 0) {
    327       continue;
    328     }
    329     if (ePersudoType == FDE_CSSPERSUDO_NONE) {
    330       MatchRules(pCache, rules.GetUniversalRuleData(), ePersudoType);
    331       if (pCache->HashTag()) {
    332         MatchRules(pCache, rules.GetTagRuleData(pCache->HashTag()),
    333                    ePersudoType);
    334       }
    335       int32_t iCount = pCache->CountHashClass();
    336       for (int32_t i = 0; i < iCount; i++) {
    337         pCache->SetClassIndex(i);
    338         MatchRules(pCache, rules.GetClassRuleData(pCache->HashClass()),
    339                    ePersudoType);
    340       }
    341     } else {
    342       MatchRules(pCache, rules.GetPersudoRuleData(), ePersudoType);
    343     }
    344     if (m_MatchedRules.GetSize() > 0) {
    345       SortRulesTo(matchedDecls);
    346       m_MatchedRules.RemoveAt(0, m_MatchedRules.GetSize());
    347     }
    348   }
    349   return matchedDecls.GetSize();
    350 }
    351 inline void CFDE_CSSStyleSelector::MatchRules(FDE_LPCSSTAGCACHE pCache,
    352                                               FDE_LPCSSRULEDATA pList,
    353                                               FDE_CSSPERSUDO ePersudoType) {
    354   while (pList != NULL) {
    355     if (MatchSelector(pCache, pList->pSelector, ePersudoType)) {
    356       m_MatchedRules.Add(pList);
    357     }
    358     pList = pList->pNext;
    359   }
    360 }
    361 FX_BOOL CFDE_CSSStyleSelector::MatchSelector(FDE_LPCSSTAGCACHE pCache,
    362                                              IFDE_CSSSelector* pSel,
    363                                              FDE_CSSPERSUDO ePersudoType) {
    364   FX_DWORD dwHash;
    365   while (pSel != NULL && pCache != NULL) {
    366     switch (pSel->GetType()) {
    367       case FDE_CSSSELECTORTYPE_Descendant:
    368         dwHash = pSel->GetNameHash();
    369         while ((pCache = pCache->GetParent()) != NULL) {
    370           if (dwHash != FDE_CSSUNIVERSALHASH && dwHash != pCache->HashTag()) {
    371             continue;
    372           }
    373           if (MatchSelector(pCache, pSel->GetNextSelector(), ePersudoType)) {
    374             return TRUE;
    375           }
    376         }
    377         return FALSE;
    378       case FDE_CSSSELECTORTYPE_ID:
    379         dwHash = pCache->HashID();
    380         if (dwHash != pSel->GetNameHash()) {
    381           return FALSE;
    382         }
    383         break;
    384       case FDE_CSSSELECTORTYPE_Class:
    385         dwHash = pCache->HashClass();
    386         if (dwHash != pSel->GetNameHash()) {
    387           return FALSE;
    388         }
    389         break;
    390       case FDE_CSSSELECTORTYPE_Element:
    391         dwHash = pSel->GetNameHash();
    392         if (dwHash != FDE_CSSUNIVERSALHASH && dwHash != pCache->HashTag()) {
    393           return FALSE;
    394         }
    395         break;
    396       case FDE_CSSSELECTORTYPE_Persudo:
    397         dwHash = FDE_GetCSSPersudoByEnum(ePersudoType)->dwHash;
    398         if (dwHash != pSel->GetNameHash()) {
    399           return FALSE;
    400         }
    401         break;
    402       default:
    403         FXSYS_assert(FALSE);
    404         break;
    405     }
    406     pSel = pSel->GetNextSelector();
    407   }
    408   return pSel == NULL && pCache != NULL;
    409 }
    410 void CFDE_CSSStyleSelector::SortRulesTo(CFDE_CSSDeclarationArray& matchDecls) {
    411   for (int32_t j = m_MatchedRules.GetUpperBound(); j >= 0; --j) {
    412     FDE_LPCSSRULEDATA& pMin = m_MatchedRules.ElementAt(j);
    413     FX_DWORD dwMin = pMin->dwPriority;
    414     for (int32_t i = j - 1; i >= 0; --i) {
    415       FDE_LPCSSRULEDATA& pCur = m_MatchedRules.ElementAt(i);
    416       if (dwMin > pCur->dwPriority) {
    417         dwMin = pCur->dwPriority;
    418         FDE_LPCSSRULEDATA p = pMin;
    419         pMin = pCur;
    420         pCur = p;
    421       }
    422     }
    423     matchDecls.Add(pMin->pDeclaration);
    424   }
    425 }
    426 void CFDE_CSSStyleSelector::ComputeStyle(
    427     IFDE_CSSTagProvider* pTag,
    428     const IFDE_CSSDeclaration** ppDeclArray,
    429     int32_t iDeclCount,
    430     IFDE_CSSComputedStyle* pDestStyle) {
    431   CFDE_CSSComputedStyle* pComputedStyle = (CFDE_CSSComputedStyle*)pDestStyle;
    432   FXSYS_assert(pTag && iDeclCount >= 0 && pComputedStyle != NULL);
    433   FX_POSITION pos = pTag->GetFirstAttribute();
    434   if (pos != NULL) {
    435     if (m_pInlineStyleStore == NULL) {
    436       m_pInlineStyleStore = FX_CreateAllocator(FX_ALLOCTYPE_Static, 2048, 0);
    437     }
    438     CFDE_CSSDeclaration* pDecl = NULL;
    439     CFX_WideStringC wsAttri, wsValue;
    440     FX_DWORD dwAttriHash;
    441     do {
    442       pTag->GetNextAttribute(pos, wsAttri, wsValue);
    443       dwAttriHash =
    444           FX_HashCode_String_GetW(wsAttri.GetPtr(), wsAttri.GetLength(), TRUE);
    445       static const FX_DWORD s_dwStyleHash =
    446           FX_HashCode_String_GetW(L"style", 5, TRUE);
    447       static const FX_DWORD s_dwAlignHash =
    448           FX_HashCode_String_GetW(L"align", 5, TRUE);
    449       if (dwAttriHash == s_dwStyleHash) {
    450         if (pDecl == NULL) {
    451           pDecl = FDE_NewWith(m_pInlineStyleStore) CFDE_CSSDeclaration;
    452         }
    453         AppendInlineStyle(pDecl, wsValue.GetPtr(), wsValue.GetLength());
    454       } else if (dwAttriHash == s_dwAlignHash) {
    455         if (pDecl == NULL) {
    456           pDecl = FDE_NewWith(m_pInlineStyleStore) CFDE_CSSDeclaration;
    457         }
    458         FDE_CSSPROPERTYARGS args;
    459         args.pStringCache = NULL;
    460         args.pStaticStore = m_pInlineStyleStore;
    461         args.pProperty = FDE_GetCSSPropertyByEnum(FDE_CSSPROPERTY_TextAlign);
    462         pDecl->AddProperty(&args, wsValue.GetPtr(), wsValue.GetLength());
    463       }
    464     } while (pos != NULL);
    465     if (pDecl != NULL) {
    466       CFDE_CSSDeclarationArray decls;
    467       decls.SetSize(iDeclCount + 1);
    468       IFDE_CSSDeclaration** ppInline = decls.GetData();
    469       FXSYS_memcpy(ppInline, ppDeclArray,
    470                    iDeclCount * sizeof(IFDE_CSSDeclaration*));
    471       ppInline[iDeclCount++] = pDecl;
    472       ApplyDeclarations(TRUE, (const IFDE_CSSDeclaration**)ppInline, iDeclCount,
    473                         pDestStyle);
    474       ApplyDeclarations(FALSE, (const IFDE_CSSDeclaration**)ppInline,
    475                         iDeclCount, pDestStyle);
    476       return;
    477     }
    478   }
    479   if (iDeclCount > 0) {
    480     FXSYS_assert(ppDeclArray != NULL);
    481     ApplyDeclarations(TRUE, ppDeclArray, iDeclCount, pDestStyle);
    482     ApplyDeclarations(FALSE, ppDeclArray, iDeclCount, pDestStyle);
    483   }
    484 }
    485 void CFDE_CSSStyleSelector::ApplyDeclarations(
    486     FX_BOOL bPriority,
    487     const IFDE_CSSDeclaration** ppDeclArray,
    488     int32_t iDeclCount,
    489     IFDE_CSSComputedStyle* pDestStyle) {
    490   CFDE_CSSComputedStyle* pComputedStyle = (CFDE_CSSComputedStyle*)pDestStyle;
    491   IFDE_CSSValue* pVal;
    492   FX_BOOL bImportant;
    493   int32_t i;
    494   if (bPriority) {
    495     IFDE_CSSValue *pLastest = NULL, *pImportant = NULL;
    496     for (i = 0; i < iDeclCount; ++i) {
    497       pVal = ppDeclArray[i]->GetProperty(FDE_CSSPROPERTY_FontSize, bImportant);
    498       if (pVal == NULL) {
    499         continue;
    500       } else if (bImportant) {
    501         pImportant = pVal;
    502       } else {
    503         pLastest = pVal;
    504       }
    505     }
    506     if (pImportant) {
    507       ApplyProperty(FDE_CSSPROPERTY_FontSize, pImportant, pComputedStyle);
    508     } else if (pLastest) {
    509       ApplyProperty(FDE_CSSPROPERTY_FontSize, pLastest, pComputedStyle);
    510     }
    511   } else {
    512     CFDE_CSSDeclarationArray importants;
    513     const IFDE_CSSDeclaration* pDecl = NULL;
    514     FDE_CSSPROPERTY eProp;
    515     FX_POSITION pos;
    516     for (i = 0; i < iDeclCount; ++i) {
    517       pDecl = ppDeclArray[i];
    518       pos = pDecl->GetStartPosition();
    519       while (pos != NULL) {
    520         pDecl->GetNextProperty(pos, eProp, pVal, bImportant);
    521         if (eProp == FDE_CSSPROPERTY_FontSize) {
    522           continue;
    523         } else if (!bImportant) {
    524           ApplyProperty(eProp, pVal, pComputedStyle);
    525         } else if (importants.GetSize() == 0 ||
    526                    importants[importants.GetUpperBound()] != pDecl) {
    527           importants.Add((IFDE_CSSDeclaration*)pDecl);
    528         }
    529       }
    530     }
    531     iDeclCount = importants.GetSize();
    532     for (i = 0; i < iDeclCount; ++i) {
    533       pDecl = importants[i];
    534       pos = pDecl->GetStartPosition();
    535       while (pos != NULL) {
    536         pDecl->GetNextProperty(pos, eProp, pVal, bImportant);
    537         if (bImportant && eProp != FDE_CSSPROPERTY_FontSize) {
    538           ApplyProperty(eProp, pVal, pComputedStyle);
    539         }
    540       }
    541     }
    542     CFX_WideString wsName, wsValue;
    543     pos = pDecl->GetStartCustom();
    544     while (pos) {
    545       pDecl->GetNextCustom(pos, wsName, wsValue);
    546       pComputedStyle->AddCustomStyle(wsName, wsValue);
    547     }
    548   }
    549 }
    550 void CFDE_CSSStyleSelector::AppendInlineStyle(CFDE_CSSDeclaration* pDecl,
    551                                               const FX_WCHAR* psz,
    552                                               int32_t iLen) {
    553   FXSYS_assert(pDecl != NULL && psz != NULL && iLen > 0);
    554   IFDE_CSSSyntaxParser* pSyntax = IFDE_CSSSyntaxParser::Create();
    555   if (pSyntax == NULL) {
    556     return;
    557   }
    558   if (pSyntax->Init(psz, iLen, 32, TRUE)) {
    559     int32_t iLen;
    560     const FX_WCHAR* psz;
    561     FDE_CSSPROPERTYARGS args;
    562     args.pStringCache = NULL;
    563     args.pStaticStore = m_pInlineStyleStore;
    564     args.pProperty = NULL;
    565     CFX_WideString wsName;
    566     for (;;) {
    567       FDE_CSSSYNTAXSTATUS eStatus = pSyntax->DoSyntaxParse();
    568       if (eStatus == FDE_CSSSYNTAXSTATUS_PropertyName) {
    569         psz = pSyntax->GetCurrentString(iLen);
    570         args.pProperty = FDE_GetCSSPropertyByName(psz, iLen);
    571         if (args.pProperty == NULL) {
    572           wsName = CFX_WideStringC(psz, iLen);
    573         }
    574       } else if (eStatus == FDE_CSSSYNTAXSTATUS_PropertyValue) {
    575         if (args.pProperty != NULL) {
    576           psz = pSyntax->GetCurrentString(iLen);
    577           if (iLen > 0) {
    578             pDecl->AddProperty(&args, psz, iLen);
    579           }
    580         } else if (iLen > 0) {
    581           psz = pSyntax->GetCurrentString(iLen);
    582           if (iLen > 0) {
    583             pDecl->AddProperty(&args, wsName, wsName.GetLength(), psz, iLen);
    584           }
    585         }
    586       } else {
    587         break;
    588       }
    589     }
    590   }
    591   pSyntax->Release();
    592 }
    593 #define FDE_CSSNONINHERITS (pComputedStyle->m_NonInheritedData)
    594 #define FDE_CSSINHERITS (pComputedStyle->m_InheritedData)
    595 #define FDE_CSSFONTSIZE (FDE_CSSINHERITS.m_fFontSize)
    596 void CFDE_CSSStyleSelector::ApplyProperty(
    597     FDE_CSSPROPERTY eProperty,
    598     IFDE_CSSValue* pValue,
    599     CFDE_CSSComputedStyle* pComputedStyle) {
    600   if (pValue->GetType() == FDE_CSSVALUETYPE_Primitive) {
    601     IFDE_CSSPrimitiveValue* pPrimitive = (IFDE_CSSPrimitiveValue*)pValue;
    602     FDE_CSSPRIMITIVETYPE eType = pPrimitive->GetPrimitiveType();
    603     switch (eProperty) {
    604       case FDE_CSSPROPERTY_Display:
    605         if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
    606           FDE_CSSNONINHERITS.m_eDisplay = ToDisplay(pPrimitive->GetEnum());
    607         }
    608         break;
    609       case FDE_CSSPROPERTY_FontSize: {
    610         FX_FLOAT& fFontSize = FDE_CSSFONTSIZE;
    611         if (eType >= FDE_CSSPRIMITIVETYPE_Number &&
    612             eType <= FDE_CSSPRIMITIVETYPE_PC) {
    613           fFontSize = ApplyNumber(eType, pPrimitive->GetFloat(), fFontSize);
    614         } else if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
    615           fFontSize = ToFontSize(pPrimitive->GetEnum(), fFontSize);
    616         }
    617       } break;
    618       case FDE_CSSPROPERTY_LineHeight:
    619         if (eType == FDE_CSSPRIMITIVETYPE_Number) {
    620           FDE_CSSINHERITS.m_fLineHeight =
    621               pPrimitive->GetFloat() * FDE_CSSFONTSIZE;
    622         } else if (eType > FDE_CSSPRIMITIVETYPE_Number &&
    623                    eType <= FDE_CSSPRIMITIVETYPE_PC) {
    624           FDE_CSSINHERITS.m_fLineHeight =
    625               ApplyNumber(eType, pPrimitive->GetFloat(), FDE_CSSFONTSIZE);
    626         }
    627         break;
    628       case FDE_CSSPROPERTY_TextAlign:
    629         if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
    630           FDE_CSSINHERITS.m_eTextAligh = ToTextAlign(pPrimitive->GetEnum());
    631         }
    632         break;
    633       case FDE_CSSPROPERTY_TextIndent:
    634         SetLengthWithPercent(FDE_CSSINHERITS.m_TextIndent, eType, pPrimitive,
    635                              FDE_CSSFONTSIZE);
    636         break;
    637       case FDE_CSSPROPERTY_FontWeight:
    638         if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
    639           FDE_CSSINHERITS.m_wFontWeight = ToFontWeight(pPrimitive->GetEnum());
    640         } else if (eType == FDE_CSSPRIMITIVETYPE_Number) {
    641           int32_t iValue = (int32_t)pPrimitive->GetFloat() / 100;
    642           if (iValue >= 1 && iValue <= 9) {
    643             FDE_CSSINHERITS.m_wFontWeight = iValue * 100;
    644           }
    645         }
    646         break;
    647       case FDE_CSSPROPERTY_FontStyle:
    648         if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
    649           FDE_CSSINHERITS.m_eFontStyle = ToFontStyle(pPrimitive->GetEnum());
    650         }
    651         break;
    652       case FDE_CSSPROPERTY_Color:
    653         if (eType == FDE_CSSPRIMITIVETYPE_RGB) {
    654           FDE_CSSINHERITS.m_dwFontColor = pPrimitive->GetRGBColor();
    655         }
    656         break;
    657       case FDE_CSSPROPERTY_MarginLeft:
    658         FDE_CSSNONINHERITS.m_bHasMargin |=
    659             SetLengthWithPercent(FDE_CSSNONINHERITS.m_MarginWidth.left, eType,
    660                                  pPrimitive, FDE_CSSFONTSIZE);
    661         break;
    662       case FDE_CSSPROPERTY_MarginTop:
    663         FDE_CSSNONINHERITS.m_bHasMargin |=
    664             SetLengthWithPercent(FDE_CSSNONINHERITS.m_MarginWidth.top, eType,
    665                                  pPrimitive, FDE_CSSFONTSIZE);
    666         break;
    667       case FDE_CSSPROPERTY_MarginRight:
    668         FDE_CSSNONINHERITS.m_bHasMargin |=
    669             SetLengthWithPercent(FDE_CSSNONINHERITS.m_MarginWidth.right, eType,
    670                                  pPrimitive, FDE_CSSFONTSIZE);
    671         break;
    672       case FDE_CSSPROPERTY_MarginBottom:
    673         FDE_CSSNONINHERITS.m_bHasMargin |=
    674             SetLengthWithPercent(FDE_CSSNONINHERITS.m_MarginWidth.bottom, eType,
    675                                  pPrimitive, FDE_CSSFONTSIZE);
    676         break;
    677       case FDE_CSSPROPERTY_PaddingLeft:
    678         FDE_CSSNONINHERITS.m_bHasPadding |=
    679             SetLengthWithPercent(FDE_CSSNONINHERITS.m_PaddingWidth.left, eType,
    680                                  pPrimitive, FDE_CSSFONTSIZE);
    681         break;
    682       case FDE_CSSPROPERTY_PaddingTop:
    683         FDE_CSSNONINHERITS.m_bHasPadding |=
    684             SetLengthWithPercent(FDE_CSSNONINHERITS.m_PaddingWidth.top, eType,
    685                                  pPrimitive, FDE_CSSFONTSIZE);
    686         break;
    687       case FDE_CSSPROPERTY_PaddingRight:
    688         FDE_CSSNONINHERITS.m_bHasPadding |=
    689             SetLengthWithPercent(FDE_CSSNONINHERITS.m_PaddingWidth.right, eType,
    690                                  pPrimitive, FDE_CSSFONTSIZE);
    691         break;
    692       case FDE_CSSPROPERTY_PaddingBottom:
    693         FDE_CSSNONINHERITS.m_bHasPadding |=
    694             SetLengthWithPercent(FDE_CSSNONINHERITS.m_PaddingWidth.bottom,
    695                                  eType, pPrimitive, FDE_CSSFONTSIZE);
    696         break;
    697       case FDE_CSSPROPERTY_BorderLeftWidth:
    698         FDE_CSSNONINHERITS.m_bHasBorder |=
    699             SetLengthWithPercent(FDE_CSSNONINHERITS.m_BorderWidth.left, eType,
    700                                  pPrimitive, FDE_CSSFONTSIZE);
    701         break;
    702       case FDE_CSSPROPERTY_BorderTopWidth:
    703         FDE_CSSNONINHERITS.m_bHasBorder |=
    704             SetLengthWithPercent(FDE_CSSNONINHERITS.m_BorderWidth.top, eType,
    705                                  pPrimitive, FDE_CSSFONTSIZE);
    706         break;
    707       case FDE_CSSPROPERTY_BorderRightWidth:
    708         FDE_CSSNONINHERITS.m_bHasBorder |=
    709             SetLengthWithPercent(FDE_CSSNONINHERITS.m_BorderWidth.right, eType,
    710                                  pPrimitive, FDE_CSSFONTSIZE);
    711         break;
    712       case FDE_CSSPROPERTY_BorderBottomWidth:
    713         FDE_CSSNONINHERITS.m_bHasBorder |=
    714             SetLengthWithPercent(FDE_CSSNONINHERITS.m_BorderWidth.bottom, eType,
    715                                  pPrimitive, FDE_CSSFONTSIZE);
    716         break;
    717       case FDE_CSSPROPERTY_BorderLeftStyle:
    718         if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
    719           FDE_CSSNONINHERITS.m_eBDRLeftStyle =
    720               ToBorderStyle(pPrimitive->GetEnum());
    721         }
    722         break;
    723       case FDE_CSSPROPERTY_BorderTopStyle:
    724         if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
    725           FDE_CSSNONINHERITS.m_eBDRTopStyle =
    726               ToBorderStyle(pPrimitive->GetEnum());
    727         }
    728         break;
    729       case FDE_CSSPROPERTY_BorderRightStyle:
    730         if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
    731           FDE_CSSNONINHERITS.m_eBDRRightStyle =
    732               ToBorderStyle(pPrimitive->GetEnum());
    733         }
    734         break;
    735       case FDE_CSSPROPERTY_BorderBottomStyle:
    736         if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
    737           FDE_CSSNONINHERITS.m_eBDRBottomStyle =
    738               ToBorderStyle(pPrimitive->GetEnum());
    739         }
    740         break;
    741       case FDE_CSSPROPERTY_BorderLeftColor:
    742         if (eType == FDE_CSSPRIMITIVETYPE_RGB) {
    743           FDE_CSSNONINHERITS.m_dwBDRLeftColor = pPrimitive->GetRGBColor();
    744         }
    745         break;
    746       case FDE_CSSPROPERTY_BorderTopColor:
    747         if (eType == FDE_CSSPRIMITIVETYPE_RGB) {
    748           FDE_CSSNONINHERITS.m_dwBDRTopColor = pPrimitive->GetRGBColor();
    749         }
    750         break;
    751       case FDE_CSSPROPERTY_BorderRightColor:
    752         if (eType == FDE_CSSPRIMITIVETYPE_RGB) {
    753           FDE_CSSNONINHERITS.m_dwBDRRightColor = pPrimitive->GetRGBColor();
    754         }
    755         break;
    756       case FDE_CSSPROPERTY_BorderBottomColor:
    757         if (eType == FDE_CSSPRIMITIVETYPE_RGB) {
    758           FDE_CSSNONINHERITS.m_dwBDRBottomColor = pPrimitive->GetRGBColor();
    759         }
    760         break;
    761       case FDE_CSSPROPERTY_ListStyleType:
    762         if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
    763           FDE_CSSNONINHERITS.m_eListStyleType =
    764               ToListStyleType(pPrimitive->GetEnum());
    765         }
    766         break;
    767       case FDE_CSSPROPERTY_ListStylePosition:
    768         if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
    769           FDE_CSSNONINHERITS.m_eListStylePosition =
    770               ToListStylePosition(pPrimitive->GetEnum());
    771         }
    772         break;
    773       case FDE_CSSPROPERTY_BackgroundColor:
    774         if (eType == FDE_CSSPRIMITIVETYPE_RGB) {
    775           FDE_CSSNONINHERITS.m_dwBKGColor = pPrimitive->GetRGBColor();
    776         } else if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
    777           FDE_CSSNONINHERITS.m_dwBKGColor = 0;
    778         }
    779         break;
    780       case FDE_CSSPROPERTY_Visibility:
    781         if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
    782           FDE_CSSINHERITS.m_eVisibility = ToVisibility(pPrimitive->GetEnum());
    783         }
    784         break;
    785       case FDE_CSSPROPERTY_Width:
    786         SetLengthWithPercent(FDE_CSSNONINHERITS.m_BoxSize.cx, eType, pPrimitive,
    787                              FDE_CSSFONTSIZE);
    788         break;
    789       case FDE_CSSPROPERTY_Height:
    790         SetLengthWithPercent(FDE_CSSNONINHERITS.m_BoxSize.cy, eType, pPrimitive,
    791                              FDE_CSSFONTSIZE);
    792         break;
    793       case FDE_CSSPROPERTY_MinWidth:
    794         SetLengthWithPercent(FDE_CSSNONINHERITS.m_MinBoxSize.cx, eType,
    795                              pPrimitive, FDE_CSSFONTSIZE);
    796         break;
    797       case FDE_CSSPROPERTY_MinHeight:
    798         SetLengthWithPercent(FDE_CSSNONINHERITS.m_MinBoxSize.cy, eType,
    799                              pPrimitive, FDE_CSSFONTSIZE);
    800         break;
    801       case FDE_CSSPROPERTY_MaxWidth:
    802         SetLengthWithPercent(FDE_CSSNONINHERITS.m_MaxBoxSize.cx, eType,
    803                              pPrimitive, FDE_CSSFONTSIZE);
    804         break;
    805       case FDE_CSSPROPERTY_MaxHeight:
    806         SetLengthWithPercent(FDE_CSSNONINHERITS.m_MaxBoxSize.cy, eType,
    807                              pPrimitive, FDE_CSSFONTSIZE);
    808         break;
    809       case FDE_CSSPROPERTY_VerticalAlign:
    810         if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
    811           FDE_CSSNONINHERITS.m_eVerticalAlign =
    812               ToVerticalAlign(pPrimitive->GetEnum());
    813         } else if (eType >= FDE_CSSPRIMITIVETYPE_Number &&
    814                    eType <= FDE_CSSPRIMITIVETYPE_PC) {
    815           FDE_CSSNONINHERITS.m_eVerticalAlign = FDE_CSSVERTICALALIGN_Number;
    816           FDE_CSSNONINHERITS.m_fVerticalAlign =
    817               ApplyNumber(eType, pPrimitive->GetFloat(), FDE_CSSFONTSIZE);
    818         }
    819         break;
    820       case FDE_CSSPROPERTY_WhiteSpace:
    821         if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
    822           FDE_CSSINHERITS.m_eWhiteSpace = ToWhiteSpace(pPrimitive->GetEnum());
    823         }
    824         break;
    825       case FDE_CSSPROPERTY_TextTransform:
    826         if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
    827           FDE_CSSINHERITS.m_eTextTransform =
    828               ToTextTransform(pPrimitive->GetEnum());
    829         }
    830         break;
    831       case FDE_CSSPROPERTY_FontVariant:
    832         if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
    833           FDE_CSSINHERITS.m_eFontVariant = ToFontVariant(pPrimitive->GetEnum());
    834         }
    835         break;
    836       case FDE_CSSPROPERTY_LetterSpacing:
    837         if (eType == FDE_CSSPRIMITIVETYPE_Percent) {
    838           break;
    839         } else if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
    840           FDE_CSSINHERITS.m_LetterSpacing.Set(FDE_CSSLENGTHUNIT_Normal);
    841         } else if (eType >= FDE_CSSPRIMITIVETYPE_Number &&
    842                    eType <= FDE_CSSPRIMITIVETYPE_PC) {
    843           SetLengthWithPercent(FDE_CSSINHERITS.m_LetterSpacing, eType,
    844                                pPrimitive, FDE_CSSFONTSIZE);
    845         }
    846         break;
    847       case FDE_CSSPROPERTY_WordSpacing:
    848         if (eType == FDE_CSSPRIMITIVETYPE_Percent) {
    849           break;
    850         } else if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
    851           FDE_CSSINHERITS.m_WordSpacing.Set(FDE_CSSLENGTHUNIT_Normal);
    852         } else if (eType >= FDE_CSSPRIMITIVETYPE_Number &&
    853                    eType <= FDE_CSSPRIMITIVETYPE_PC) {
    854           SetLengthWithPercent(FDE_CSSINHERITS.m_WordSpacing, eType, pPrimitive,
    855                                FDE_CSSFONTSIZE);
    856         }
    857         break;
    858       case FDE_CSSPROPERTY_Float:
    859         if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
    860           FDE_CSSNONINHERITS.m_eFloat = ToFloat(pPrimitive->GetEnum());
    861         }
    862         break;
    863       case FDE_CSSPROPERTY_Clear:
    864         if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
    865           FDE_CSSNONINHERITS.m_eClear = ToClear(pPrimitive->GetEnum());
    866         }
    867         break;
    868       case FDE_CSSPROPERTY_WritingMode:
    869         if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
    870           FDE_CSSINHERITS.m_eWritingMode = ToWritingMode(pPrimitive->GetEnum());
    871         }
    872         break;
    873       case FDE_CSSPROPERTY_WordBreak:
    874         if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
    875           FDE_CSSINHERITS.m_eWordBreak = ToWordBreak(pPrimitive->GetEnum());
    876         }
    877         break;
    878       case FDE_CSSPROPERTY_Widows:
    879         if (eType == FDE_CSSPRIMITIVETYPE_Number) {
    880           FDE_CSSINHERITS.m_iWidows = (int32_t)pPrimitive->GetFloat();
    881         }
    882         break;
    883       case FDE_CSSPROPERTY_Orphans:
    884         if (eType == FDE_CSSPRIMITIVETYPE_Number) {
    885           FDE_CSSINHERITS.m_iOrphans = (int32_t)pPrimitive->GetFloat();
    886         }
    887         break;
    888       case FDE_CSSPROPERTY_TextEmphasisColor:
    889         if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
    890           switch (pPrimitive->GetEnum()) {
    891             case FDE_CSSPROPERTYVALUE_Transparent:
    892               FDE_CSSINHERITS.m_dwTextEmphasisColor = 0;
    893               FDE_CSSINHERITS.m_bTextEmphasisColorCurrent = FALSE;
    894               break;
    895             case FDE_CSSPROPERTYVALUE_Currentcolor:
    896               FDE_CSSINHERITS.m_bTextEmphasisColorCurrent = TRUE;
    897               break;
    898             default:
    899               break;
    900           }
    901         } else if (eType == FDE_CSSPRIMITIVETYPE_RGB) {
    902           FDE_CSSINHERITS.m_dwTextEmphasisColor = pPrimitive->GetRGBColor();
    903           FDE_CSSINHERITS.m_bTextEmphasisColorCurrent = FALSE;
    904         }
    905         break;
    906       case FDE_CSSPROPERTY_PageBreakBefore:
    907         if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
    908           FDE_CSSNONINHERITS.m_ePageBreakBefore =
    909               ToPageBreak(pPrimitive->GetEnum());
    910         }
    911         break;
    912       case FDE_CSSPROPERTY_PageBreakAfter:
    913         if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
    914           FDE_CSSNONINHERITS.m_ePageBreakAfter =
    915               ToPageBreak(pPrimitive->GetEnum());
    916         }
    917         break;
    918       case FDE_CSSPROPERTY_PageBreakInside:
    919         if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
    920           FDE_CSSNONINHERITS.m_ePageBreakInside =
    921               ToPageBreak(pPrimitive->GetEnum());
    922         }
    923         break;
    924       case FDE_CSSPROPERTY_OverflowX:
    925         if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
    926           FDE_CSSNONINHERITS.m_eOverflowX = ToOverflow(pPrimitive->GetEnum());
    927         }
    928         break;
    929       case FDE_CSSPROPERTY_OverflowY:
    930         if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
    931           FDE_CSSNONINHERITS.m_eOverflowY = ToOverflow(pPrimitive->GetEnum());
    932         }
    933         break;
    934       case FDE_CSSPROPERTY_LineBreak:
    935         if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
    936           FDE_CSSINHERITS.m_eLineBreak = ToLineBreak(pPrimitive->GetEnum());
    937         }
    938         break;
    939       case FDE_CSSPROPERTY_ColumnCount:
    940         if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
    941           FDE_CSSNONINHERITS.m_ColumnCount.Set(FDE_CSSLENGTHUNIT_Auto);
    942         } else if (eType == FDE_CSSPRIMITIVETYPE_Number) {
    943           FDE_CSSNONINHERITS.m_ColumnCount.Set(FDE_CSSLENGTHUNIT_Point,
    944                                                pPrimitive->GetFloat());
    945         }
    946         break;
    947       case FDE_CSSPROPERTY_ColumnGap:
    948         SetLengthWithPercent(FDE_CSSNONINHERITS.m_ColumnGap, eType, pPrimitive,
    949                              FDE_CSSFONTSIZE);
    950         break;
    951       case FDE_CSSPROPERTY_ColumnRuleColor:
    952         if (eType == FDE_CSSPRIMITIVETYPE_RGB) {
    953           FDE_CSSNONINHERITS.m_dwColumnRuleColor = pPrimitive->GetRGBColor();
    954           FDE_CSSNONINHERITS.m_bColumnRuleColorSame = FALSE;
    955         }
    956         break;
    957       case FDE_CSSPROPERTY_ColumnRuleStyle:
    958         if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
    959           FDE_CSSNONINHERITS.m_eColumnRuleStyle =
    960               ToBorderStyle(pPrimitive->GetEnum());
    961         }
    962         break;
    963       case FDE_CSSPROPERTY_ColumnRuleWidth:
    964         SetLengthWithPercent(FDE_CSSNONINHERITS.m_ColumnRuleWidth, eType,
    965                              pPrimitive, FDE_CSSFONTSIZE);
    966         break;
    967       case FDE_CSSPROPERTY_ColumnWidth:
    968         SetLengthWithPercent(FDE_CSSNONINHERITS.m_ColumnWidth, eType,
    969                              pPrimitive, FDE_CSSFONTSIZE);
    970         break;
    971       case FDE_CSSPROPERTY_BackgroundImage:
    972         if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
    973           FDE_CSSNONINHERITS.m_pszBKGImage = NULL;
    974         } else if (eType == FDE_CSSPRIMITIVETYPE_URI) {
    975           int32_t iLength;
    976           FDE_CSSNONINHERITS.m_pszBKGImage = pPrimitive->GetString(iLength);
    977         }
    978         break;
    979       case FDE_CSSPROPERTY_Position:
    980         if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
    981           FDE_CSSNONINHERITS.m_ePosition = ToPosition(pPrimitive->GetEnum());
    982         }
    983         break;
    984       case FDE_CSSPROPERTY_Top:
    985         SetLengthWithPercent(FDE_CSSNONINHERITS.m_Top, eType, pPrimitive,
    986                              FDE_CSSFONTSIZE);
    987         break;
    988       case FDE_CSSPROPERTY_Bottom:
    989         SetLengthWithPercent(FDE_CSSNONINHERITS.m_Bottom, eType, pPrimitive,
    990                              FDE_CSSFONTSIZE);
    991         break;
    992       case FDE_CSSPROPERTY_Left:
    993         SetLengthWithPercent(FDE_CSSNONINHERITS.m_Left, eType, pPrimitive,
    994                              FDE_CSSFONTSIZE);
    995         break;
    996       case FDE_CSSPROPERTY_Right:
    997         SetLengthWithPercent(FDE_CSSNONINHERITS.m_Right, eType, pPrimitive,
    998                              FDE_CSSFONTSIZE);
    999         break;
   1000       case FDE_CSSPROPERTY_ListStyleImage:
   1001         if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
   1002           FDE_CSSINHERITS.m_pszListStyleImage = NULL;
   1003         } else if (eType == FDE_CSSPRIMITIVETYPE_URI) {
   1004           int32_t iLength;
   1005           FDE_CSSINHERITS.m_pszListStyleImage = pPrimitive->GetString(iLength);
   1006         }
   1007         break;
   1008       case FDE_CSSPROPERTY_CaptionSide:
   1009         if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
   1010           FDE_CSSINHERITS.m_eCaptionSide = ToCaptionSide(pPrimitive->GetEnum());
   1011         }
   1012         break;
   1013       case FDE_CSSPROPERTY_BackgroundRepeat:
   1014         if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
   1015           FDE_CSSNONINHERITS.m_eBKGRepeat = ToBKGRepeat(pPrimitive->GetEnum());
   1016         }
   1017         break;
   1018       case FDE_CSSPROPERTY_BackgroundAttachment:
   1019         if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
   1020           FDE_CSSNONINHERITS.m_eBKGAttachment =
   1021               ToBKGAttachment(pPrimitive->GetEnum());
   1022         }
   1023         break;
   1024       case FDE_CSSPROPERTY_RubyAlign:
   1025         if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
   1026           FDE_CSSINHERITS.m_eRubyAlign = ToRubyAlign(pPrimitive->GetEnum());
   1027         }
   1028         break;
   1029       case FDE_CSSPROPERTY_RubyOverhang:
   1030         if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
   1031           FDE_CSSINHERITS.m_eRubyOverhang =
   1032               ToRubyOverhang(pPrimitive->GetEnum());
   1033         }
   1034         break;
   1035       case FDE_CSSPROPERTY_RubyPosition:
   1036         if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
   1037           FDE_CSSINHERITS.m_eRubyPosition =
   1038               ToRubyPosition(pPrimitive->GetEnum());
   1039         }
   1040         break;
   1041       case FDE_CSSPROPERTY_RubySpan:
   1042         FDE_CSSNONINHERITS.m_pRubySpan = pPrimitive;
   1043         break;
   1044       default:
   1045         break;
   1046     }
   1047   } else if (pValue->GetType() == FDE_CSSVALUETYPE_List) {
   1048     IFDE_CSSValueList* pList = (IFDE_CSSValueList*)pValue;
   1049     int32_t iCount = pList->CountValues();
   1050     if (iCount > 0) {
   1051       switch (eProperty) {
   1052         case FDE_CSSPROPERTY_FontFamily:
   1053           FDE_CSSINHERITS.m_pFontFamily = pList;
   1054           break;
   1055         case FDE_CSSPROPERTY_TextDecoration:
   1056           FDE_CSSNONINHERITS.m_dwTextDecoration = ToTextDecoration(pList);
   1057           break;
   1058         case FDE_CSSPROPERTY_CounterIncrement: {
   1059           if (FDE_CSSNONINHERITS.m_pCounterStyle == NULL) {
   1060             FDE_CSSNONINHERITS.m_pCounterStyle = new CFDE_CSSCounterStyle;
   1061           }
   1062           FDE_CSSNONINHERITS.m_pCounterStyle->SetCounterIncrementList(pList);
   1063         } break;
   1064         case FDE_CSSPROPERTY_CounterReset: {
   1065           if (FDE_CSSNONINHERITS.m_pCounterStyle == NULL) {
   1066             FDE_CSSNONINHERITS.m_pCounterStyle = new CFDE_CSSCounterStyle;
   1067           }
   1068           FDE_CSSNONINHERITS.m_pCounterStyle->SetCounterResetList(pList);
   1069         } break;
   1070         case FDE_CSSPROPERTY_Content:
   1071           FDE_CSSNONINHERITS.m_pContentList = pList;
   1072           break;
   1073         case FDE_CSSPROPERTY_Quotes:
   1074           FDE_CSSINHERITS.m_pQuotes = pList;
   1075           break;
   1076         case FDE_CSSPROPERTY_TextCombine: {
   1077           for (int32_t i = 0; i < pList->CountValues(); i++) {
   1078             IFDE_CSSPrimitiveValue* pVal =
   1079                 (IFDE_CSSPrimitiveValue*)pList->GetValue(i);
   1080             switch (pVal->GetPrimitiveType()) {
   1081               case FDE_CSSPRIMITIVETYPE_Enum: {
   1082                 switch (pVal->GetEnum()) {
   1083                   case FDE_CSSPROPERTYVALUE_None: {
   1084                     FDE_CSSNONINHERITS.m_eTextCombine = FDE_CSSTEXTCOMBINE_None;
   1085                     FDE_CSSNONINHERITS.m_bHasTextCombineNumber = FALSE;
   1086                   } break;
   1087                   case FDE_CSSPROPERTYVALUE_Horizontal: {
   1088                     FDE_CSSNONINHERITS.m_eTextCombine =
   1089                         FDE_CSSTEXTCOMBINE_Horizontal;
   1090                     FDE_CSSNONINHERITS.m_bHasTextCombineNumber = FALSE;
   1091                   } break;
   1092                   default:
   1093                     break;
   1094                 }
   1095               } break;
   1096               case FDE_CSSPRIMITIVETYPE_Number:
   1097                 FDE_CSSNONINHERITS.m_fTextCombineNumber = pVal->GetFloat();
   1098                 break;
   1099               default:
   1100                 break;
   1101             }
   1102           }
   1103         } break;
   1104         case FDE_CSSPROPERTY_TextEmphasisStyle: {
   1105           FDE_CSSTEXTEMPHASISFILL eFill;
   1106           FDE_CSSTEXTEMPHASISMARK eMark;
   1107           for (int32_t i = 0; i < pList->CountValues(); i++) {
   1108             IFDE_CSSPrimitiveValue* pVal =
   1109                 (IFDE_CSSPrimitiveValue*)pList->GetValue(i);
   1110             switch (pVal->GetPrimitiveType()) {
   1111               case FDE_CSSPRIMITIVETYPE_Enum: {
   1112                 if (ToTextEmphasisFill(pVal->GetEnum(), eFill)) {
   1113                   FDE_CSSINHERITS.m_eTextEmphasisFill = eFill;
   1114                   continue;
   1115                 } else if (ToTextEmphasisMark(pVal->GetEnum(), eMark)) {
   1116                   FDE_CSSINHERITS.m_eTextEmphasisMark = eMark;
   1117                 }
   1118               } break;
   1119               case FDE_CSSPRIMITIVETYPE_String: {
   1120                 FDE_CSSINHERITS.m_eTextEmphasisMark =
   1121                     FDE_CSSTEXTEMPHASISMARK_Custom;
   1122                 int32_t iLen;
   1123                 FDE_CSSINHERITS.m_pszTextEmphasisCustomMark =
   1124                     pVal->GetString(iLen);
   1125               } break;
   1126               default:
   1127                 break;
   1128             }
   1129           }
   1130         } break;
   1131         default:
   1132           break;
   1133       }
   1134     }
   1135   } else {
   1136     FXSYS_assert(FALSE);
   1137   }
   1138 }
   1139 FX_FLOAT CFDE_CSSStyleSelector::ApplyNumber(FDE_CSSPRIMITIVETYPE eUnit,
   1140                                             FX_FLOAT fValue,
   1141                                             FX_FLOAT fPercentBase) {
   1142   switch (eUnit) {
   1143     case FDE_CSSPRIMITIVETYPE_PX:
   1144     case FDE_CSSPRIMITIVETYPE_Number:
   1145       return fValue * 72 / 96;
   1146     case FDE_CSSPRIMITIVETYPE_PT:
   1147       return fValue;
   1148     case FDE_CSSPRIMITIVETYPE_EMS:
   1149     case FDE_CSSPRIMITIVETYPE_EXS:
   1150       return fValue * fPercentBase;
   1151     case FDE_CSSPRIMITIVETYPE_Percent:
   1152       return fValue * fPercentBase / 100.0f;
   1153     case FDE_CSSPRIMITIVETYPE_CM:
   1154       return fValue * 28.3464f;
   1155     case FDE_CSSPRIMITIVETYPE_MM:
   1156       return fValue * 2.8346f;
   1157     case FDE_CSSPRIMITIVETYPE_IN:
   1158       return fValue * 72.0f;
   1159     case FDE_CSSPRIMITIVETYPE_PC:
   1160       return fValue / 12.0f;
   1161     default:
   1162       return fValue;
   1163   }
   1164 }
   1165 FDE_CSSRUBYSPAN CFDE_CSSStyleSelector::ToRubySpan(FDE_CSSPROPERTYVALUE eValue) {
   1166   switch (eValue) {
   1167     case FDE_CSSPROPERTYVALUE_None:
   1168     default:
   1169       return FDE_CSSRUBYSPAN_None;
   1170   }
   1171 }
   1172 FDE_CSSRUBYPOSITION CFDE_CSSStyleSelector::ToRubyPosition(
   1173     FDE_CSSPROPERTYVALUE eValue) {
   1174   switch (eValue) {
   1175     case FDE_CSSPROPERTYVALUE_Before:
   1176       return FDE_CSSRUBYPOSITION_Before;
   1177     case FDE_CSSPROPERTYVALUE_After:
   1178       return FDE_CSSRUBYPOSITION_After;
   1179     case FDE_CSSPROPERTYVALUE_Right:
   1180       return FDE_CSSRUBYPOSITION_Right;
   1181     case FDE_CSSPROPERTYVALUE_Inline:
   1182       return FDE_CSSRUBYPOSITION_Inline;
   1183     default:
   1184       return FDE_CSSRUBYPOSITION_Before;
   1185   }
   1186 }
   1187 FDE_CSSRUBYOVERHANG CFDE_CSSStyleSelector::ToRubyOverhang(
   1188     FDE_CSSPROPERTYVALUE eValue) {
   1189   switch (eValue) {
   1190     case FDE_CSSPROPERTYVALUE_Auto:
   1191       return FDE_CSSRUBYOVERHANG_Auto;
   1192     case FDE_CSSPROPERTYVALUE_Start:
   1193       return FDE_CSSRUBYOVERHANG_Start;
   1194     case FDE_CSSPROPERTYVALUE_End:
   1195       return FDE_CSSRUBYOVERHANG_End;
   1196     case FDE_CSSPROPERTYVALUE_None:
   1197     default:
   1198       return FDE_CSSRUBYOVERHANG_None;
   1199   }
   1200 }
   1201 FDE_CSSRUBYALIGN CFDE_CSSStyleSelector::ToRubyAlign(
   1202     FDE_CSSPROPERTYVALUE eValue) {
   1203   switch (eValue) {
   1204     case FDE_CSSPROPERTYVALUE_Auto:
   1205       return FDE_CSSRUBYALIGN_Auto;
   1206     case FDE_CSSPROPERTYVALUE_Start:
   1207       return FDE_CSSRUBYALIGN_Start;
   1208     case FDE_CSSPROPERTYVALUE_Left:
   1209       return FDE_CSSRUBYALIGN_End;
   1210     case FDE_CSSPROPERTYVALUE_Center:
   1211       return FDE_CSSRUBYALIGN_Center;
   1212     case FDE_CSSPROPERTYVALUE_End:
   1213       return FDE_CSSRUBYALIGN_End;
   1214     case FDE_CSSPROPERTYVALUE_Right:
   1215       return FDE_CSSRUBYALIGN_Right;
   1216     case FDE_CSSPROPERTYVALUE_DistributeLetter:
   1217       return FDE_CSSRUBYALIGN_DistributeLetter;
   1218     case FDE_CSSPROPERTYVALUE_DistributeSpace:
   1219       return FDE_CSSRUBYALIGN_DistributeSpace;
   1220     case FDE_CSSPROPERTYVALUE_LineEdge:
   1221       return FDE_CSSRUBYALIGN_LineEdge;
   1222     default:
   1223       return FDE_CSSRUBYALIGN_Auto;
   1224   }
   1225 }
   1226 FX_BOOL CFDE_CSSStyleSelector::ToTextEmphasisMark(
   1227     FDE_CSSPROPERTYVALUE eValue,
   1228     FDE_CSSTEXTEMPHASISMARK& eMark) {
   1229   switch (eValue) {
   1230     case FDE_CSSPROPERTYVALUE_None:
   1231       eMark = FDE_CSSTEXTEMPHASISMARK_None;
   1232       return TRUE;
   1233     case FDE_CSSPROPERTYVALUE_Dot:
   1234       eMark = FDE_CSSTEXTEMPHASISMARK_Dot;
   1235       return TRUE;
   1236     case FDE_CSSPROPERTYVALUE_Circle:
   1237       eMark = FDE_CSSTEXTEMPHASISMARK_Circle;
   1238       return TRUE;
   1239     case FDE_CSSPROPERTYVALUE_DoubleCircle:
   1240       eMark = FDE_CSSTEXTEMPHASISMARK_DoubleCircle;
   1241       return TRUE;
   1242     case FDE_CSSPROPERTYVALUE_Triangle:
   1243       eMark = FDE_CSSTEXTEMPHASISMARK_Triangle;
   1244       return TRUE;
   1245     case FDE_CSSPROPERTYVALUE_Sesame:
   1246       eMark = FDE_CSSTEXTEMPHASISMARK_Sesame;
   1247       return TRUE;
   1248     default:
   1249       return FALSE;
   1250   }
   1251 }
   1252 FX_BOOL CFDE_CSSStyleSelector::ToTextEmphasisFill(
   1253     FDE_CSSPROPERTYVALUE eValue,
   1254     FDE_CSSTEXTEMPHASISFILL& eFill) {
   1255   switch (eValue) {
   1256     case FDE_CSSPROPERTYVALUE_Filled:
   1257       eFill = FDE_CSSTEXTEMPHASISFILL_Filled;
   1258       return TRUE;
   1259     case FDE_CSSPROPERTYVALUE_Open:
   1260       eFill = FDE_CSSTEXTEMPHASISFILL_Open;
   1261       return TRUE;
   1262     default:
   1263       return FALSE;
   1264   }
   1265 }
   1266 FDE_CSSBKGATTACHMENT CFDE_CSSStyleSelector::ToBKGAttachment(
   1267     FDE_CSSPROPERTYVALUE eValue) {
   1268   switch (eValue) {
   1269     case FDE_CSSPROPERTYVALUE_Fixed:
   1270       return FDE_CSSBKGATTACHMENT_Fixed;
   1271     case FDE_CSSPROPERTYVALUE_Scroll:
   1272       return FDE_CSSBKGATTACHMENT_Scroll;
   1273     default:
   1274       return FDE_CSSBKGATTACHMENT_Fixed;
   1275   }
   1276 }
   1277 FDE_CSSCAPTIONSIDE CFDE_CSSStyleSelector::ToCaptionSide(
   1278     FDE_CSSPROPERTYVALUE eValue) {
   1279   switch (eValue) {
   1280     case FDE_CSSPROPERTYVALUE_Top:
   1281       return FDE_CSSCAPTIONSIDE_Top;
   1282     case FDE_CSSPROPERTYVALUE_Bottom:
   1283       return FDE_CSSCAPTIONSIDE_Bottom;
   1284     case FDE_CSSPROPERTYVALUE_Left:
   1285       return FDE_CSSCAPTIONSIDE_Left;
   1286     case FDE_CSSPROPERTYVALUE_Right:
   1287       return FDE_CSSCAPTIONSIDE_Right;
   1288     case FDE_CSSPROPERTYVALUE_Before:
   1289       return FDE_CSSCAPTIONSIDE_Before;
   1290     case FDE_CSSPROPERTYVALUE_After:
   1291       return FDE_CSSCAPTIONSIDE_After;
   1292     default:
   1293       return FDE_CSSCAPTIONSIDE_Top;
   1294   }
   1295 }
   1296 FDE_CSSPOSITION CFDE_CSSStyleSelector::ToPosition(FDE_CSSPROPERTYVALUE eValue) {
   1297   switch (eValue) {
   1298     case FDE_CSSPROPERTYVALUE_Static:
   1299       return FDE_CSSPOSITION_Static;
   1300     case FDE_CSSPROPERTYVALUE_Relative:
   1301       return FDE_CSSPOSITION_Relative;
   1302     case FDE_CSSPROPERTYVALUE_Fixed:
   1303       return FDE_CSSPOSITION_Fixed;
   1304     case FDE_CSSPROPERTYVALUE_Absolute:
   1305       return FDE_CSSPOSITION_Absolute;
   1306     default:
   1307       return FDE_CSSPOSITION_Static;
   1308   }
   1309 }
   1310 FDE_CSSCURSOR CFDE_CSSStyleSelector::ToCursor(FDE_CSSPROPERTYVALUE eValue) {
   1311   switch (eValue) {
   1312     case FDE_CSSPROPERTYVALUE_Auto:
   1313       return FDE_CSSCURSOR_Auto;
   1314     case FDE_CSSPROPERTYVALUE_Crosshair:
   1315       return FDE_CSSCURSOR_Crosshair;
   1316     case FDE_CSSPROPERTYVALUE_Default:
   1317       return FDE_CSSCURSOR_Default;
   1318     case FDE_CSSPROPERTYVALUE_Pointer:
   1319       return FDE_CSSCURSOR_Pointer;
   1320     case FDE_CSSPROPERTYVALUE_Move:
   1321       return FDE_CSSCURSOR_Move;
   1322     case FDE_CSSPROPERTYVALUE_EResize:
   1323       return FDE_CSSCURSOR_EResize;
   1324     case FDE_CSSPROPERTYVALUE_NeResize:
   1325       return FDE_CSSCURSOR_NeResize;
   1326     case FDE_CSSPROPERTYVALUE_NwResize:
   1327       return FDE_CSSCURSOR_NwResize;
   1328     case FDE_CSSPROPERTYVALUE_NResize:
   1329       return FDE_CSSCURSOR_NResize;
   1330     case FDE_CSSPROPERTYVALUE_SeResize:
   1331       return FDE_CSSCURSOR_SeResize;
   1332     case FDE_CSSPROPERTYVALUE_SwResize:
   1333       return FDE_CSSCURSOR_SwResize;
   1334     default:
   1335       return FDE_CSSCURSOR_Auto;
   1336   }
   1337 }
   1338 FDE_CSSBKGREPEAT CFDE_CSSStyleSelector::ToBKGRepeat(
   1339     FDE_CSSPROPERTYVALUE eValue) {
   1340   switch (eValue) {
   1341     case FDE_CSSPROPERTYVALUE_Repeat:
   1342       return FDE_CSSBKGREPEAT_Repeat;
   1343     case FDE_CSSPROPERTYVALUE_RepeatX:
   1344       return FDE_CSSBKGREPEAT_RepeatX;
   1345     case FDE_CSSPROPERTYVALUE_RepeatY:
   1346       return FDE_CSSBKGREPEAT_RepeatY;
   1347     case FDE_CSSPROPERTYVALUE_NoRepeat:
   1348       return FDE_CSSBKGREPEAT_NoRepeat;
   1349     default:
   1350       return FDE_CSSBKGREPEAT_Repeat;
   1351   }
   1352 }
   1353 FDE_CSSTEXTCOMBINE CFDE_CSSStyleSelector::ToTextCombine(
   1354     FDE_CSSPROPERTYVALUE eValue) {
   1355   switch (eValue) {
   1356     case FDE_CSSPROPERTYVALUE_Horizontal:
   1357       return FDE_CSSTEXTCOMBINE_Horizontal;
   1358     case FDE_CSSPROPERTYVALUE_None:
   1359     default:
   1360       return FDE_CSSTEXTCOMBINE_None;
   1361   }
   1362 }
   1363 FDE_CSSLINEBREAK CFDE_CSSStyleSelector::ToLineBreak(
   1364     FDE_CSSPROPERTYVALUE eValue) {
   1365   switch (eValue) {
   1366     case FDE_CSSPROPERTYVALUE_Auto:
   1367       return FDE_CSSLINEBREAK_Auto;
   1368     case FDE_CSSPROPERTYVALUE_Loose:
   1369       return FDE_CSSLINEBREAK_Loose;
   1370     case FDE_CSSPROPERTYVALUE_Normal:
   1371       return FDE_CSSLINEBREAK_Normal;
   1372     case FDE_CSSPROPERTYVALUE_Strict:
   1373       return FDE_CSSLINEBREAK_Strict;
   1374     default:
   1375       return FDE_CSSLINEBREAK_Auto;
   1376   }
   1377 }
   1378 FDE_CSSOVERFLOW CFDE_CSSStyleSelector::ToOverflow(FDE_CSSPROPERTYVALUE eValue) {
   1379   switch (eValue) {
   1380     case FDE_CSSPROPERTYVALUE_Visible:
   1381       return FDE_CSSOVERFLOW_Visible;
   1382     case FDE_CSSPROPERTYVALUE_Hidden:
   1383       return FDE_CSSOVERFLOW_Hidden;
   1384     case FDE_CSSPROPERTYVALUE_Scroll:
   1385       return FDE_CSSOVERFLOW_Scroll;
   1386     case FDE_CSSPROPERTYVALUE_Auto:
   1387       return FDE_CSSOVERFLOW_Auto;
   1388     case FDE_CSSPROPERTYVALUE_NoDisplay:
   1389       return FDE_CSSOVERFLOW_NoDisplay;
   1390     case FDE_CSSPROPERTYVALUE_NoContent:
   1391       return FDE_CSSOVERFLOW_NoContent;
   1392     default:
   1393       return FDE_CSSOVERFLOW_Visible;
   1394   }
   1395 }
   1396 FDE_CSSWRITINGMODE CFDE_CSSStyleSelector::ToWritingMode(
   1397     FDE_CSSPROPERTYVALUE eValue) {
   1398   switch (eValue) {
   1399     case FDE_CSSPROPERTYVALUE_HorizontalTb:
   1400       return FDE_CSSWRITINGMODE_HorizontalTb;
   1401     case FDE_CSSPROPERTYVALUE_VerticalRl:
   1402       return FDE_CSSWRITINGMODE_VerticalRl;
   1403     case FDE_CSSPROPERTYVALUE_VerticalLr:
   1404       return FDE_CSSWRITINGMODE_VerticalLr;
   1405     default:
   1406       return FDE_CSSWRITINGMODE_HorizontalTb;
   1407   }
   1408 }
   1409 FDE_CSSWORDBREAK CFDE_CSSStyleSelector::ToWordBreak(
   1410     FDE_CSSPROPERTYVALUE eValue) {
   1411   switch (eValue) {
   1412     case FDE_CSSPROPERTYVALUE_Normal:
   1413       return FDE_CSSWORDBREAK_Normal;
   1414     case FDE_CSSPROPERTYVALUE_KeepAll:
   1415       return FDE_CSSWORDBREAK_KeepAll;
   1416     case FDE_CSSPROPERTYVALUE_BreakAll:
   1417       return FDE_CSSWORDBREAK_BreakAll;
   1418     case FDE_CSSPROPERTYVALUE_KeepWords:
   1419       return FDE_CSSWORDBREAK_KeepWords;
   1420     default:
   1421       return FDE_CSSWORDBREAK_Normal;
   1422   }
   1423 }
   1424 FDE_CSSFLOAT CFDE_CSSStyleSelector::ToFloat(FDE_CSSPROPERTYVALUE eValue) {
   1425   switch (eValue) {
   1426     case FDE_CSSPROPERTYVALUE_Left:
   1427       return FDE_CSSFLOAT_Left;
   1428     case FDE_CSSPROPERTYVALUE_Right:
   1429       return FDE_CSSFLOAT_Right;
   1430     case FDE_CSSPROPERTYVALUE_None:
   1431       return FDE_CSSFLOAT_None;
   1432     default:
   1433       return FDE_CSSFLOAT_None;
   1434   }
   1435 }
   1436 FDE_CSSCLEAR CFDE_CSSStyleSelector::ToClear(FDE_CSSPROPERTYVALUE eValue) {
   1437   switch (eValue) {
   1438     case FDE_CSSPROPERTYVALUE_None:
   1439       return FDE_CSSCLEAR_None;
   1440     case FDE_CSSPROPERTYVALUE_Left:
   1441       return FDE_CSSCLEAR_Left;
   1442     case FDE_CSSPROPERTYVALUE_Right:
   1443       return FDE_CSSCLEAR_Right;
   1444     case FDE_CSSPROPERTYVALUE_Both:
   1445       return FDE_CSSCLEAR_Both;
   1446     default:
   1447       return FDE_CSSCLEAR_None;
   1448   }
   1449 }
   1450 FDE_CSSPAGEBREAK CFDE_CSSStyleSelector::ToPageBreak(
   1451     FDE_CSSPROPERTYVALUE eValue) {
   1452   switch (eValue) {
   1453     case FDE_CSSPROPERTYVALUE_Avoid:
   1454       return FDE_CSSPAGEBREAK_Avoid;
   1455     case FDE_CSSPROPERTYVALUE_Auto:
   1456       return FDE_CSSPAGEBREAK_Auto;
   1457     case FDE_CSSPROPERTYVALUE_Always:
   1458       return FDE_CSSPAGEBREAK_Always;
   1459     case FDE_CSSPROPERTYVALUE_Left:
   1460       return FDE_CSSPAGEBREAK_Left;
   1461     case FDE_CSSPROPERTYVALUE_Right:
   1462       return FDE_CSSPAGEBREAK_Right;
   1463     default:
   1464       return FDE_CSSPAGEBREAK_Auto;
   1465   }
   1466 }
   1467 FDE_CSSDISPLAY CFDE_CSSStyleSelector::ToDisplay(FDE_CSSPROPERTYVALUE eValue) {
   1468   switch (eValue) {
   1469     case FDE_CSSPROPERTYVALUE_Inline:
   1470       return FDE_CSSDISPLAY_Inline;
   1471     case FDE_CSSPROPERTYVALUE_Block:
   1472       return FDE_CSSDISPLAY_Block;
   1473     case FDE_CSSPROPERTYVALUE_None:
   1474       return FDE_CSSDISPLAY_None;
   1475     case FDE_CSSPROPERTYVALUE_ListItem:
   1476       return FDE_CSSDISPLAY_ListItem;
   1477     case FDE_CSSPROPERTYVALUE_TableCell:
   1478       return FDE_CSSDISPLAY_TableCell;
   1479     case FDE_CSSPROPERTYVALUE_TableRow:
   1480       return FDE_CSSDISPLAY_TableRow;
   1481     case FDE_CSSPROPERTYVALUE_Table:
   1482       return FDE_CSSDISPLAY_Table;
   1483     case FDE_CSSPROPERTYVALUE_TableCaption:
   1484       return FDE_CSSDISPLAY_TableCaption;
   1485     case FDE_CSSPROPERTYVALUE_TableRowGroup:
   1486       return FDE_CSSDISPLAY_TableRowGroup;
   1487     case FDE_CSSPROPERTYVALUE_TableHeaderGroup:
   1488       return FDE_CSSDISPLAY_TableHeaderGroup;
   1489     case FDE_CSSPROPERTYVALUE_TableFooterGroup:
   1490       return FDE_CSSDISPLAY_TableFooterGroup;
   1491     case FDE_CSSPROPERTYVALUE_TableColumnGroup:
   1492       return FDE_CSSDISPLAY_TableColumnGroup;
   1493     case FDE_CSSPROPERTYVALUE_TableColumn:
   1494       return FDE_CSSDISPLAY_TableColumn;
   1495     case FDE_CSSPROPERTYVALUE_InlineTable:
   1496       return FDE_CSSDISPLAY_InlineTable;
   1497     case FDE_CSSPROPERTYVALUE_InlineBlock:
   1498       return FDE_CSSDISPLAY_InlineBlock;
   1499     case FDE_CSSPROPERTYVALUE_RunIn:
   1500       return FDE_CSSDISPLAY_RunIn;
   1501     case FDE_CSSPROPERTYVALUE_Ruby:
   1502       return FDE_CSSDISPLAY_Ruby;
   1503     case FDE_CSSPROPERTYVALUE_RubyBase:
   1504       return FDE_CSSDISPLAY_RubyBase;
   1505     case FDE_CSSPROPERTYVALUE_RubyText:
   1506       return FDE_CSSDISPLAY_RubyText;
   1507     case FDE_CSSPROPERTYVALUE_RubyBaseGroup:
   1508       return FDE_CSSDISPLSY_RubyBaseGroup;
   1509     case FDE_CSSPROPERTYVALUE_RubyTextGroup:
   1510       return FDE_CSSDISPLAY_RubyTextGroup;
   1511     default:
   1512       return FDE_CSSDISPLAY_Inline;
   1513   }
   1514 }
   1515 FDE_CSSTEXTALIGN CFDE_CSSStyleSelector::ToTextAlign(
   1516     FDE_CSSPROPERTYVALUE eValue) {
   1517   switch (eValue) {
   1518     case FDE_CSSPROPERTYVALUE_Left:
   1519       return FDE_CSSTEXTALIGN_Left;
   1520     case FDE_CSSPROPERTYVALUE_Center:
   1521       return FDE_CSSTEXTALIGN_Center;
   1522     case FDE_CSSPROPERTYVALUE_Right:
   1523       return FDE_CSSTEXTALIGN_Right;
   1524     case FDE_CSSPROPERTYVALUE_Justify:
   1525       return FDE_CSSTEXTALIGN_Justify;
   1526     default:
   1527       return FDE_CSSTEXTALIGN_Left;
   1528   }
   1529 }
   1530 FX_WORD CFDE_CSSStyleSelector::ToFontWeight(FDE_CSSPROPERTYVALUE eValue) {
   1531   switch (eValue) {
   1532     case FDE_CSSPROPERTYVALUE_Normal:
   1533       return 400;
   1534     case FDE_CSSPROPERTYVALUE_Bold:
   1535       return 700;
   1536     case FDE_CSSPROPERTYVALUE_Bolder:
   1537       return 900;
   1538     case FDE_CSSPROPERTYVALUE_Lighter:
   1539       return 200;
   1540     default:
   1541       return 400;
   1542   }
   1543 }
   1544 FDE_CSSFONTSTYLE CFDE_CSSStyleSelector::ToFontStyle(
   1545     FDE_CSSPROPERTYVALUE eValue) {
   1546   switch (eValue) {
   1547     case FDE_CSSPROPERTYVALUE_Italic:
   1548     case FDE_CSSPROPERTYVALUE_Oblique:
   1549       return FDE_CSSFONTSTYLE_Italic;
   1550     default:
   1551       return FDE_CSSFONTSTYLE_Normal;
   1552   }
   1553 }
   1554 FDE_CSSBORDERSTYLE CFDE_CSSStyleSelector::ToBorderStyle(
   1555     FDE_CSSPROPERTYVALUE eValue) {
   1556   switch (eValue) {
   1557     case FDE_CSSPROPERTYVALUE_None:
   1558       return FDE_CSSBORDERSTYLE_None;
   1559     case FDE_CSSPROPERTYVALUE_Solid:
   1560       return FDE_CSSBORDERSTYLE_Solid;
   1561     case FDE_CSSPROPERTYVALUE_Hidden:
   1562       return FDE_CSSBORDERSTYLE_Hidden;
   1563     case FDE_CSSPROPERTYVALUE_Dotted:
   1564       return FDE_CSSBORDERSTYLE_Dotted;
   1565     case FDE_CSSPROPERTYVALUE_Dashed:
   1566       return FDE_CSSBORDERSTYLE_Dashed;
   1567     case FDE_CSSPROPERTYVALUE_Double:
   1568       return FDE_CSSBORDERSTYLE_Double;
   1569     case FDE_CSSPROPERTYVALUE_Groove:
   1570       return FDE_CSSBORDERSTYLE_Groove;
   1571     case FDE_CSSPROPERTYVALUE_Ridge:
   1572       return FDE_CSSBORDERSTYLE_Ridge;
   1573     case FDE_CSSPROPERTYVALUE_Inset:
   1574       return FDE_CSSBORDERSTYLE_Inset;
   1575     case FDE_CSSPROPERTYVALUE_Outset:
   1576       return FDE_CSSBORDERSTYLE_outset;
   1577     default:
   1578       return FDE_CSSBORDERSTYLE_None;
   1579   }
   1580 }
   1581 FX_BOOL CFDE_CSSStyleSelector::SetLengthWithPercent(
   1582     FDE_CSSLENGTH& width,
   1583     FDE_CSSPRIMITIVETYPE eType,
   1584     IFDE_CSSPrimitiveValue* pPrimitive,
   1585     FX_FLOAT fFontSize) {
   1586   if (eType == FDE_CSSPRIMITIVETYPE_Percent) {
   1587     width.Set(FDE_CSSLENGTHUNIT_Percent, pPrimitive->GetFloat() / 100.0f);
   1588     return width.NonZero();
   1589   } else if (eType >= FDE_CSSPRIMITIVETYPE_Number &&
   1590              eType <= FDE_CSSPRIMITIVETYPE_PC) {
   1591     FX_FLOAT fValue = ApplyNumber(eType, pPrimitive->GetFloat(), fFontSize);
   1592     width.Set(FDE_CSSLENGTHUNIT_Point, fValue);
   1593     return width.NonZero();
   1594   } else if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
   1595     switch (pPrimitive->GetEnum()) {
   1596       case FDE_CSSPROPERTYVALUE_Auto:
   1597         width.Set(FDE_CSSLENGTHUNIT_Auto);
   1598         return TRUE;
   1599       case FDE_CSSPROPERTYVALUE_None:
   1600         width.Set(FDE_CSSLENGTHUNIT_None);
   1601         return TRUE;
   1602       case FDE_CSSPROPERTYVALUE_Thin:
   1603         width.Set(FDE_CSSLENGTHUNIT_Point, 2);
   1604         return TRUE;
   1605       case FDE_CSSPROPERTYVALUE_Medium:
   1606         width.Set(FDE_CSSLENGTHUNIT_Point, 3);
   1607         return TRUE;
   1608       case FDE_CSSPROPERTYVALUE_Thick:
   1609         width.Set(FDE_CSSLENGTHUNIT_Point, 4);
   1610         return TRUE;
   1611       default:
   1612         return FALSE;
   1613     }
   1614   }
   1615   return FALSE;
   1616 }
   1617 FX_FLOAT CFDE_CSSStyleSelector::ToFontSize(FDE_CSSPROPERTYVALUE eValue,
   1618                                            FX_FLOAT fCurFontSize) {
   1619   switch (eValue) {
   1620     case FDE_CSSPROPERTYVALUE_XxSmall:
   1621       return m_fDefFontSize / 1.2f / 1.2f / 1.2f;
   1622     case FDE_CSSPROPERTYVALUE_XSmall:
   1623       return m_fDefFontSize / 1.2f / 1.2f;
   1624     case FDE_CSSPROPERTYVALUE_Small:
   1625       return m_fDefFontSize / 1.2f;
   1626     case FDE_CSSPROPERTYVALUE_Medium:
   1627       return m_fDefFontSize;
   1628     case FDE_CSSPROPERTYVALUE_Large:
   1629       return m_fDefFontSize * 1.2f;
   1630     case FDE_CSSPROPERTYVALUE_XLarge:
   1631       return m_fDefFontSize * 1.2f * 1.2f;
   1632     case FDE_CSSPROPERTYVALUE_XxLarge:
   1633       return m_fDefFontSize * 1.2f * 1.2f * 1.2f;
   1634     case FDE_CSSPROPERTYVALUE_Larger:
   1635       return fCurFontSize * 1.2f;
   1636     case FDE_CSSPROPERTYVALUE_Smaller:
   1637       return fCurFontSize / 1.2f;
   1638     default:
   1639       return fCurFontSize;
   1640   }
   1641 }
   1642 FDE_CSSVERTICALALIGN CFDE_CSSStyleSelector::ToVerticalAlign(
   1643     FDE_CSSPROPERTYVALUE eValue) {
   1644   switch (eValue) {
   1645     case FDE_CSSPROPERTYVALUE_Baseline:
   1646       return FDE_CSSVERTICALALIGN_Baseline;
   1647     case FDE_CSSPROPERTYVALUE_Middle:
   1648       return FDE_CSSVERTICALALIGN_Middle;
   1649     case FDE_CSSPROPERTYVALUE_Bottom:
   1650       return FDE_CSSVERTICALALIGN_Bottom;
   1651     case FDE_CSSPROPERTYVALUE_Super:
   1652       return FDE_CSSVERTICALALIGN_Super;
   1653     case FDE_CSSPROPERTYVALUE_Sub:
   1654       return FDE_CSSVERTICALALIGN_Sub;
   1655     case FDE_CSSPROPERTYVALUE_Top:
   1656       return FDE_CSSVERTICALALIGN_Top;
   1657     case FDE_CSSPROPERTYVALUE_TextTop:
   1658       return FDE_CSSVERTICALALIGN_TextTop;
   1659     case FDE_CSSPROPERTYVALUE_TextBottom:
   1660       return FDE_CSSVERTICALALIGN_TextBottom;
   1661     default:
   1662       return FDE_CSSVERTICALALIGN_Baseline;
   1663   }
   1664 }
   1665 FDE_CSSLISTSTYLETYPE CFDE_CSSStyleSelector::ToListStyleType(
   1666     FDE_CSSPROPERTYVALUE eValue) {
   1667   switch (eValue) {
   1668     case FDE_CSSPROPERTYVALUE_None:
   1669       return FDE_CSSLISTSTYLETYPE_None;
   1670     case FDE_CSSPROPERTYVALUE_Disc:
   1671       return FDE_CSSLISTSTYLETYPE_Disc;
   1672     case FDE_CSSPROPERTYVALUE_Circle:
   1673       return FDE_CSSLISTSTYLETYPE_Circle;
   1674     case FDE_CSSPROPERTYVALUE_Square:
   1675       return FDE_CSSLISTSTYLETYPE_Square;
   1676     case FDE_CSSPROPERTYVALUE_Decimal:
   1677       return FDE_CSSLISTSTYLETYPE_Decimal;
   1678     case FDE_CSSPROPERTYVALUE_DecimalLeadingZero:
   1679       return FDE_CSSLISTSTYLETYPE_DecimalLeadingZero;
   1680     case FDE_CSSPROPERTYVALUE_LowerRoman:
   1681       return FDE_CSSLISTSTYLETYPE_LowerRoman;
   1682     case FDE_CSSPROPERTYVALUE_UpperRoman:
   1683       return FDE_CSSLISTSTYLETYPE_UpperRoman;
   1684     case FDE_CSSPROPERTYVALUE_LowerGreek:
   1685       return FDE_CSSLISTSTYLETYPE_LowerGreek;
   1686     case FDE_CSSPROPERTYVALUE_LowerLatin:
   1687       return FDE_CSSLISTSTYLETYPE_LowerLatin;
   1688     case FDE_CSSPROPERTYVALUE_UpperLatin:
   1689       return FDE_CSSLISTSTYLETYPE_UpperLatin;
   1690     case FDE_CSSPROPERTYVALUE_Armenian:
   1691       return FDE_CSSLISTSTYLETYPE_Armenian;
   1692     case FDE_CSSPROPERTYVALUE_Georgian:
   1693       return FDE_CSSLISTSTYLETYPE_Georgian;
   1694     case FDE_CSSPROPERTYVALUE_LowerAlpha:
   1695       return FDE_CSSLISTSTYLETYPE_LowerAlpha;
   1696     case FDE_CSSPROPERTYVALUE_UpperAlpha:
   1697       return FDE_CSSLISTSTYLETYPE_UpperAlpha;
   1698     case FDE_CSSPROPERTYVALUE_CjkIdeographic:
   1699       return FDE_CSSLISTSTYLETYPE_CjkIdeographic;
   1700     case FDE_CSSPROPERTYVALUE_Hebrew:
   1701       return FDE_CSSLISTSTYLETYPE_Hebrew;
   1702     case FDE_CSSLISTSTYLETYPE_Hiragana:
   1703       return FDE_CSSLISTSTYLETYPE_Hiragana;
   1704     case FDE_CSSLISTSTYLETYPE_HiraganaIroha:
   1705       return FDE_CSSLISTSTYLETYPE_HiraganaIroha;
   1706     case FDE_CSSLISTSTYLETYPE_Katakana:
   1707       return FDE_CSSLISTSTYLETYPE_Katakana;
   1708     case FDE_CSSLISTSTYLETYPE_KatakanaIroha:
   1709       return FDE_CSSLISTSTYLETYPE_KatakanaIroha;
   1710     default:
   1711       return FDE_CSSLISTSTYLETYPE_Disc;
   1712   }
   1713 }
   1714 FDE_CSSLISTSTYLEPOSITION CFDE_CSSStyleSelector::ToListStylePosition(
   1715     FDE_CSSPROPERTYVALUE eValue) {
   1716   return eValue == FDE_CSSPROPERTYVALUE_Inside
   1717              ? FDE_CSSLISTSTYLEPOSITION_Inside
   1718              : FDE_CSSLISTSTYLEPOSITION_Outside;
   1719 }
   1720 FDE_CSSVISIBILITY CFDE_CSSStyleSelector::ToVisibility(
   1721     FDE_CSSPROPERTYVALUE eValue) {
   1722   switch (eValue) {
   1723     case FDE_CSSPROPERTYVALUE_Visible:
   1724       return FDE_CSSVISIBILITY_Visible;
   1725     case FDE_CSSPROPERTYVALUE_Hidden:
   1726       return FDE_CSSVISIBILITY_Hidden;
   1727     case FDE_CSSPROPERTYVALUE_Collapse:
   1728       return FDE_CSSVISIBILITY_Collapse;
   1729     default:
   1730       return FDE_CSSVISIBILITY_Visible;
   1731   }
   1732 }
   1733 FDE_CSSWHITESPACE CFDE_CSSStyleSelector::ToWhiteSpace(
   1734     FDE_CSSPROPERTYVALUE eValue) {
   1735   switch (eValue) {
   1736     case FDE_CSSPROPERTYVALUE_Normal:
   1737       return FDE_CSSWHITESPACE_Normal;
   1738     case FDE_CSSPROPERTYVALUE_Pre:
   1739       return FDE_CSSWHITESPACE_Pre;
   1740     case FDE_CSSPROPERTYVALUE_Nowrap:
   1741       return FDE_CSSWHITESPACE_Nowrap;
   1742     case FDE_CSSPROPERTYVALUE_PreWrap:
   1743       return FDE_CSSWHITESPACE_PreWrap;
   1744     case FDE_CSSPROPERTYVALUE_PreLine:
   1745       return FDE_CSSWHITESPACE_PreLine;
   1746     default:
   1747       return FDE_CSSWHITESPACE_Normal;
   1748   }
   1749 }
   1750 FX_DWORD CFDE_CSSStyleSelector::ToTextDecoration(IFDE_CSSValueList* pValue) {
   1751   FX_DWORD dwDecoration = 0;
   1752   for (int32_t i = pValue->CountValues() - 1; i >= 0; --i) {
   1753     IFDE_CSSPrimitiveValue* pPrimitive =
   1754         (IFDE_CSSPrimitiveValue*)pValue->GetValue(i);
   1755     if (pPrimitive->GetPrimitiveType() == FDE_CSSPRIMITIVETYPE_Enum) {
   1756       switch (pPrimitive->GetEnum()) {
   1757         case FDE_CSSPROPERTYVALUE_Underline:
   1758           dwDecoration |= FDE_CSSTEXTDECORATION_Underline;
   1759           break;
   1760         case FDE_CSSPROPERTYVALUE_LineThrough:
   1761           dwDecoration |= FDE_CSSTEXTDECORATION_LineThrough;
   1762           break;
   1763         case FDE_CSSPROPERTYVALUE_Overline:
   1764           dwDecoration |= FDE_CSSTEXTDECORATION_Overline;
   1765           break;
   1766         case FDE_CSSPROPERTYVALUE_Blink:
   1767           dwDecoration |= FDE_CSSTEXTDECORATION_Blink;
   1768           break;
   1769         case FDE_CSSPROPERTYVALUE_Double:
   1770           dwDecoration |= FDE_CSSTEXTDECORATION_Double;
   1771           break;
   1772         default:
   1773           break;
   1774       }
   1775     }
   1776   }
   1777   return dwDecoration;
   1778 }
   1779 FDE_CSSTEXTTRANSFORM CFDE_CSSStyleSelector::ToTextTransform(
   1780     FDE_CSSPROPERTYVALUE eValue) {
   1781   switch (eValue) {
   1782     case FDE_CSSPROPERTYVALUE_None:
   1783       return FDE_CSSTEXTTRANSFORM_None;
   1784     case FDE_CSSPROPERTYVALUE_Capitalize:
   1785       return FDE_CSSTEXTTRANSFORM_Capitalize;
   1786     case FDE_CSSPROPERTYVALUE_Uppercase:
   1787       return FDE_CSSTEXTTRANSFORM_UpperCase;
   1788     case FDE_CSSPROPERTYVALUE_Lowercase:
   1789       return FDE_CSSTEXTTRANSFORM_LowerCase;
   1790     default:
   1791       return FDE_CSSTEXTTRANSFORM_None;
   1792   }
   1793 }
   1794 FDE_CSSFONTVARIANT CFDE_CSSStyleSelector::ToFontVariant(
   1795     FDE_CSSPROPERTYVALUE eValue) {
   1796   return eValue == FDE_CSSPROPERTYVALUE_SmallCaps ? FDE_CSSFONTVARIANT_SmallCaps
   1797                                                   : FDE_CSSFONTVARIANT_Normal;
   1798 }
   1799