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"
FindIndex(const FX_WCHAR * pszIdentifier)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 }
DoUpdateIndex(IFDE_CSSValueList * pList)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 }
UpdateIndex()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 }
GetTextEmphasisMark() const74 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 }
_FDE_CSSRULEDATA(IFDE_CSSSelector * pSel,IFDE_CSSDeclaration * pDecl,FX_DWORD dwPos)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 }
Clear()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 }
AddRulesFrom(const CFDE_CSSStyleSheetArray & sheets,FX_DWORD dwMediaList,IFX_FontMgr * pFontMgr)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 }
AddRulesFrom(IFDE_CSSStyleSheet * pStyleSheet,IFDE_CSSRule * pRule,FX_DWORD dwMediaList,IFX_FontMgr * pFontMgr)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 }
AddRuleTo(CFX_MapPtrToPtr & map,FX_DWORD dwKey,IFDE_CSSSelector * pSel,IFDE_CSSDeclaration * pDecl)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 }
AddRuleTo(FDE_LPCSSRULEDATA & pList,FDE_LPCSSRULEDATA pData)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 }
NewRuleData(IFDE_CSSSelector * pSel,IFDE_CSSDeclaration * pDecl)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 }
Create()208 IFDE_CSSStyleSelector* IFDE_CSSStyleSelector::Create() {
209   return new CFDE_CSSStyleSelector;
210 }
CFDE_CSSStyleSelector()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 }
~CFDE_CSSStyleSelector()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 }
SetFontMgr(IFX_FontMgr * pFontMgr)235 void CFDE_CSSStyleSelector::SetFontMgr(IFX_FontMgr* pFontMgr) {
236   m_pFontMgr = pFontMgr;
237 }
SetDefFontSize(FX_FLOAT fFontSize)238 void CFDE_CSSStyleSelector::SetDefFontSize(FX_FLOAT fFontSize) {
239   FXSYS_assert(fFontSize > 0);
240   m_fDefFontSize = fFontSize;
241 }
InitAccelerator()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 }
CreateComputedStyle(IFDE_CSSComputedStyle * pParentStyle)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 }
SetStyleSheet(FDE_CSSSTYLESHEETGROUP eType,IFDE_CSSStyleSheet * pSheet)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 }
SetStyleSheets(FDE_CSSSTYLESHEETGROUP eType,const CFDE_CSSStyleSheetArray * pArray)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 }
SetStylePriority(FDE_CSSSTYLESHEETGROUP eType,FDE_CSSSTYLESHEETPRIORITY ePriority)290 void CFDE_CSSStyleSelector::SetStylePriority(
291     FDE_CSSSTYLESHEETGROUP eType,
292     FDE_CSSSTYLESHEETPRIORITY ePriority) {
293   m_ePriorities[ePriority] = eType;
294 }
UpdateStyleIndex(FX_DWORD dwMediaList)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 }
Reset()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 }
MatchDeclarations(IFDE_CSSTagProvider * pTag,CFDE_CSSDeclarationArray & matchedDecls,FDE_CSSPERSUDO ePersudoType)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 }
MatchRules(FDE_LPCSSTAGCACHE pCache,FDE_LPCSSRULEDATA pList,FDE_CSSPERSUDO ePersudoType)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 }
MatchSelector(FDE_LPCSSTAGCACHE pCache,IFDE_CSSSelector * pSel,FDE_CSSPERSUDO ePersudoType)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 }
SortRulesTo(CFDE_CSSDeclarationArray & matchDecls)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 }
ComputeStyle(IFDE_CSSTagProvider * pTag,const IFDE_CSSDeclaration ** ppDeclArray,int32_t iDeclCount,IFDE_CSSComputedStyle * pDestStyle)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 }
ApplyDeclarations(FX_BOOL bPriority,const IFDE_CSSDeclaration ** ppDeclArray,int32_t iDeclCount,IFDE_CSSComputedStyle * pDestStyle)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 }
AppendInlineStyle(CFDE_CSSDeclaration * pDecl,const FX_WCHAR * psz,int32_t iLen)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)
ApplyProperty(FDE_CSSPROPERTY eProperty,IFDE_CSSValue * pValue,CFDE_CSSComputedStyle * pComputedStyle)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 }
ApplyNumber(FDE_CSSPRIMITIVETYPE eUnit,FX_FLOAT fValue,FX_FLOAT fPercentBase)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 }
ToRubySpan(FDE_CSSPROPERTYVALUE eValue)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 }
ToRubyPosition(FDE_CSSPROPERTYVALUE eValue)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 }
ToRubyOverhang(FDE_CSSPROPERTYVALUE eValue)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 }
ToRubyAlign(FDE_CSSPROPERTYVALUE eValue)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 }
ToTextEmphasisMark(FDE_CSSPROPERTYVALUE eValue,FDE_CSSTEXTEMPHASISMARK & eMark)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 }
ToTextEmphasisFill(FDE_CSSPROPERTYVALUE eValue,FDE_CSSTEXTEMPHASISFILL & eFill)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 }
ToBKGAttachment(FDE_CSSPROPERTYVALUE eValue)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 }
ToCaptionSide(FDE_CSSPROPERTYVALUE eValue)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 }
ToPosition(FDE_CSSPROPERTYVALUE eValue)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 }
ToCursor(FDE_CSSPROPERTYVALUE eValue)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 }
ToBKGRepeat(FDE_CSSPROPERTYVALUE eValue)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 }
ToTextCombine(FDE_CSSPROPERTYVALUE eValue)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 }
ToLineBreak(FDE_CSSPROPERTYVALUE eValue)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 }
ToOverflow(FDE_CSSPROPERTYVALUE eValue)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 }
ToWritingMode(FDE_CSSPROPERTYVALUE eValue)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 }
ToWordBreak(FDE_CSSPROPERTYVALUE eValue)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 }
ToFloat(FDE_CSSPROPERTYVALUE eValue)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 }
ToClear(FDE_CSSPROPERTYVALUE eValue)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 }
ToPageBreak(FDE_CSSPROPERTYVALUE eValue)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 }
ToDisplay(FDE_CSSPROPERTYVALUE eValue)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 }
ToTextAlign(FDE_CSSPROPERTYVALUE eValue)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 }
ToFontWeight(FDE_CSSPROPERTYVALUE eValue)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 }
ToFontStyle(FDE_CSSPROPERTYVALUE eValue)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 }
ToBorderStyle(FDE_CSSPROPERTYVALUE eValue)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 }
SetLengthWithPercent(FDE_CSSLENGTH & width,FDE_CSSPRIMITIVETYPE eType,IFDE_CSSPrimitiveValue * pPrimitive,FX_FLOAT fFontSize)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 }
ToFontSize(FDE_CSSPROPERTYVALUE eValue,FX_FLOAT fCurFontSize)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 }
ToVerticalAlign(FDE_CSSPROPERTYVALUE eValue)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 }
ToListStyleType(FDE_CSSPROPERTYVALUE eValue)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 }
ToListStylePosition(FDE_CSSPROPERTYVALUE eValue)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 }
ToVisibility(FDE_CSSPROPERTYVALUE eValue)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 }
ToWhiteSpace(FDE_CSSPROPERTYVALUE eValue)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 }
ToTextDecoration(IFDE_CSSValueList * pValue)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 }
ToTextTransform(FDE_CSSPROPERTYVALUE eValue)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 }
ToFontVariant(FDE_CSSPROPERTYVALUE eValue)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