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 #ifndef XFA_FDE_CSS_FDE_CSSSTYLESELECTOR_H_
8 #define XFA_FDE_CSS_FDE_CSSSTYLESELECTOR_H_
9 
10 #include <vector>
11 
12 #include "core/fxcrt/include/fx_ext.h"
13 #include "xfa/fde/css/fde_css.h"
14 #include "xfa/fde/css/fde_csscache.h"
15 #include "xfa/fde/css/fde_cssdeclaration.h"
16 #include "xfa/fgas/crt/fgas_memory.h"
17 #include "xfa/fgas/crt/fgas_system.h"
18 
19 class CFDE_CSSAccelerator;
20 class CFDE_CSSComputedStyle;
21 class CXFA_CSSTagProvider;
22 
23 class FDE_CSSRuleData : public CFX_Target {
24  public:
25   FDE_CSSRuleData(CFDE_CSSSelector* pSel,
26                   CFDE_CSSDeclaration* pDecl,
27                   uint32_t dwPos);
28 
29   CFDE_CSSSelector* pSelector;
30   CFDE_CSSDeclaration* pDeclaration;
31   uint32_t dwPriority;
32   FDE_CSSRuleData* pNext;
33 };
34 
35 class CFDE_CSSRuleCollection : public CFX_Target {
36  public:
37   CFDE_CSSRuleCollection();
38   ~CFDE_CSSRuleCollection() override;
39 
40   void AddRulesFrom(const CFDE_CSSStyleSheetArray& sheets,
41                     uint32_t dwMediaList,
42                     IFGAS_FontMgr* pFontMgr);
43   void Clear();
44 
CountSelectors()45   int32_t CountSelectors() const { return m_iSelectors; }
GetIDRuleData(uint32_t dwIDHash)46   FDE_CSSRuleData* GetIDRuleData(uint32_t dwIDHash) {
47     void* pData;
48     return m_IDRules.Lookup((void*)(uintptr_t)dwIDHash, pData)
49                ? (FDE_CSSRuleData*)pData
50                : nullptr;
51   }
GetTagRuleData(uint32_t dwTagHasn)52   FDE_CSSRuleData* GetTagRuleData(uint32_t dwTagHasn) {
53     void* pData;
54     return m_TagRules.Lookup((void*)(uintptr_t)dwTagHasn, pData)
55                ? (FDE_CSSRuleData*)pData
56                : nullptr;
57   }
GetClassRuleData(uint32_t dwIDHash)58   FDE_CSSRuleData* GetClassRuleData(uint32_t dwIDHash) {
59     void* pData;
60     return m_ClassRules.Lookup((void*)(uintptr_t)dwIDHash, pData)
61                ? (FDE_CSSRuleData*)pData
62                : nullptr;
63   }
GetUniversalRuleData()64   FDE_CSSRuleData* GetUniversalRuleData() { return m_pUniversalRules; }
GetPersudoRuleData()65   FDE_CSSRuleData* GetPersudoRuleData() { return m_pPersudoRules; }
66 
67   IFX_MemoryAllocator* m_pStaticStore;
68 
69  protected:
70   void AddRulesFrom(IFDE_CSSStyleSheet* pStyleSheet,
71                     IFDE_CSSRule* pRule,
72                     uint32_t dwMediaList,
73                     IFGAS_FontMgr* pFontMgr);
74   void AddRuleTo(CFX_MapPtrToPtr& map,
75                  uint32_t dwKey,
76                  CFDE_CSSSelector* pSel,
77                  CFDE_CSSDeclaration* pDecl);
78   FX_BOOL AddRuleTo(FDE_CSSRuleData*& pList, FDE_CSSRuleData* pData);
79   FDE_CSSRuleData* NewRuleData(CFDE_CSSSelector* pSel,
80                                CFDE_CSSDeclaration* pDecl);
81   CFX_MapPtrToPtr m_IDRules;
82   CFX_MapPtrToPtr m_TagRules;
83   CFX_MapPtrToPtr m_ClassRules;
84   FDE_CSSRuleData* m_pUniversalRules;
85   FDE_CSSRuleData* m_pPersudoRules;
86   int32_t m_iSelectors;
87 };
88 
89 class CFDE_CSSStyleSelector : public CFX_Target {
90  public:
91   CFDE_CSSStyleSelector();
92   ~CFDE_CSSStyleSelector() override;
93 
94   void SetFontMgr(IFGAS_FontMgr* pFontMgr);
95   void SetDefFontSize(FX_FLOAT fFontSize);
96 
97   FX_BOOL SetStyleSheet(FDE_CSSSTYLESHEETGROUP eType,
98                         IFDE_CSSStyleSheet* pSheet);
99   FX_BOOL SetStyleSheets(FDE_CSSSTYLESHEETGROUP eType,
100                          const CFDE_CSSStyleSheetArray* pArray);
101   void SetStylePriority(FDE_CSSSTYLESHEETGROUP eType,
102                         FDE_CSSSTYLESHEETPRIORITY ePriority);
103   void UpdateStyleIndex(uint32_t dwMediaList);
104   CFDE_CSSAccelerator* InitAccelerator();
105   IFDE_CSSComputedStyle* CreateComputedStyle(
106       IFDE_CSSComputedStyle* pParentStyle);
107   int32_t MatchDeclarations(CXFA_CSSTagProvider* pTag,
108                             CFDE_CSSDeclarationArray& matchedDecls,
109                             FDE_CSSPERSUDO ePersudoType = FDE_CSSPERSUDO_NONE);
110   void ComputeStyle(CXFA_CSSTagProvider* pTag,
111                     const CFDE_CSSDeclaration** ppDeclArray,
112                     int32_t iDeclCount,
113                     IFDE_CSSComputedStyle* pDestStyle);
114 
115  protected:
116   void Reset();
117   void MatchRules(FDE_CSSTagCache* pCache,
118                   FDE_CSSRuleData* pList,
119                   FDE_CSSPERSUDO ePersudoType);
120   FX_BOOL MatchSelector(FDE_CSSTagCache* pCache,
121                         CFDE_CSSSelector* pSel,
122                         FDE_CSSPERSUDO ePersudoType);
123   void AppendInlineStyle(CFDE_CSSDeclaration* pDecl,
124                          const FX_WCHAR* psz,
125                          int32_t iLen);
126   void ApplyDeclarations(FX_BOOL bPriority,
127                          const CFDE_CSSDeclaration** ppDeclArray,
128                          int32_t iDeclCount,
129                          IFDE_CSSComputedStyle* pDestStyle);
130   void ApplyProperty(FDE_CSSPROPERTY eProperty,
131                      IFDE_CSSValue* pValue,
132                      CFDE_CSSComputedStyle* pComputedStyle);
133 
134   FX_FLOAT ApplyNumber(FDE_CSSPRIMITIVETYPE eUnit,
135                        FX_FLOAT fValue,
136                        FX_FLOAT fPercentBase);
137   FX_BOOL SetLengthWithPercent(FDE_CSSLENGTH& width,
138                                FDE_CSSPRIMITIVETYPE eType,
139                                IFDE_CSSPrimitiveValue* pPrimitive,
140                                FX_FLOAT fFontSize);
141   FX_FLOAT ToFontSize(FDE_CSSPROPERTYVALUE eValue, FX_FLOAT fCurFontSize);
142   FDE_CSSDISPLAY ToDisplay(FDE_CSSPROPERTYVALUE eValue);
143   FDE_CSSTEXTALIGN ToTextAlign(FDE_CSSPROPERTYVALUE eValue);
144   uint16_t ToFontWeight(FDE_CSSPROPERTYVALUE eValue);
145   FDE_CSSFONTSTYLE ToFontStyle(FDE_CSSPROPERTYVALUE eValue);
146   FDE_CSSBORDERSTYLE ToBorderStyle(FDE_CSSPROPERTYVALUE eValue);
147   FDE_CSSVERTICALALIGN ToVerticalAlign(FDE_CSSPROPERTYVALUE eValue);
148   FDE_CSSLISTSTYLETYPE ToListStyleType(FDE_CSSPROPERTYVALUE eValue);
149   FDE_CSSLISTSTYLEPOSITION ToListStylePosition(FDE_CSSPROPERTYVALUE eValue);
150   FDE_CSSVISIBILITY ToVisibility(FDE_CSSPROPERTYVALUE eValue);
151   FDE_CSSWHITESPACE ToWhiteSpace(FDE_CSSPROPERTYVALUE eValue);
152   uint32_t ToTextDecoration(IFDE_CSSValueList* pList);
153   FDE_CSSTEXTTRANSFORM ToTextTransform(FDE_CSSPROPERTYVALUE eValue);
154   FDE_CSSFONTVARIANT ToFontVariant(FDE_CSSPROPERTYVALUE eValue);
155   FDE_CSSFLOAT ToFloat(FDE_CSSPROPERTYVALUE eValue);
156   FDE_CSSCLEAR ToClear(FDE_CSSPROPERTYVALUE eValue);
157   FDE_CSSWRITINGMODE ToWritingMode(FDE_CSSPROPERTYVALUE eValue);
158   FDE_CSSWORDBREAK ToWordBreak(FDE_CSSPROPERTYVALUE eValue);
159   FDE_CSSPAGEBREAK ToPageBreak(FDE_CSSPROPERTYVALUE eValue);
160   FDE_CSSOVERFLOW ToOverflow(FDE_CSSPROPERTYVALUE eValue);
161   FDE_CSSLINEBREAK ToLineBreak(FDE_CSSPROPERTYVALUE eValue);
162   FDE_CSSTEXTCOMBINE ToTextCombine(FDE_CSSPROPERTYVALUE eValue);
163   FX_BOOL ToTextEmphasisMark(FDE_CSSPROPERTYVALUE eValue,
164                              FDE_CSSTEXTEMPHASISMARK& eMark);
165   FX_BOOL ToTextEmphasisFill(FDE_CSSPROPERTYVALUE eValue,
166                              FDE_CSSTEXTEMPHASISFILL& eFill);
167   FDE_CSSCURSOR ToCursor(FDE_CSSPROPERTYVALUE eValue);
168   FDE_CSSPOSITION ToPosition(FDE_CSSPROPERTYVALUE eValue);
169   FDE_CSSCAPTIONSIDE ToCaptionSide(FDE_CSSPROPERTYVALUE eValue);
170   FDE_CSSBKGREPEAT ToBKGRepeat(FDE_CSSPROPERTYVALUE eValue);
171   FDE_CSSBKGATTACHMENT ToBKGAttachment(FDE_CSSPROPERTYVALUE eValue);
172   FDE_CSSRUBYALIGN ToRubyAlign(FDE_CSSPROPERTYVALUE eValue);
173   FDE_CSSRUBYOVERHANG ToRubyOverhang(FDE_CSSPROPERTYVALUE eValue);
174   FDE_CSSRUBYPOSITION ToRubyPosition(FDE_CSSPROPERTYVALUE eValue);
175   FDE_CSSRUBYSPAN ToRubySpan(FDE_CSSPROPERTYVALUE eValue);
176 
177   IFGAS_FontMgr* m_pFontMgr;
178   FX_FLOAT m_fDefFontSize;
179   IFX_MemoryAllocator* m_pRuleDataStore;
180   CFDE_CSSStyleSheetArray m_SheetGroups[FDE_CSSSTYLESHEETGROUP_MAX];
181   CFDE_CSSRuleCollection m_RuleCollection[FDE_CSSSTYLESHEETGROUP_MAX];
182   FDE_CSSSTYLESHEETGROUP m_ePriorities[FDE_CSSSTYLESHEETPRIORITY_MAX];
183   IFX_MemoryAllocator* m_pInlineStyleStore;
184   IFX_MemoryAllocator* m_pFixedStyleStore;
185   CFDE_CSSAccelerator* m_pAccelerator;
186   std::vector<FDE_CSSRuleData*> m_MatchedRules;
187 };
188 
189 struct FDE_CSSCOUNTERDATA {
190  public:
FDE_CSSCOUNTERDATAFDE_CSSCOUNTERDATA191   FDE_CSSCOUNTERDATA() { FXSYS_memset(this, 0, sizeof(FDE_CSSCOUNTERDATA)); }
GetCounterIncrementFDE_CSSCOUNTERDATA192   FX_BOOL GetCounterIncrement(int32_t& iValue) {
193     iValue = m_iIncVal;
194     return m_bIncrement;
195   }
GetCounterResetFDE_CSSCOUNTERDATA196   FX_BOOL GetCounterReset(int32_t& iValue) {
197     iValue = m_iResetVal;
198     return m_bReset;
199   }
200 
201   const FX_WCHAR* m_pszIdent;
202   FX_BOOL m_bIncrement;
203   FX_BOOL m_bReset;
204   int32_t m_iIncVal;
205   int32_t m_iResetVal;
206 };
207 
208 class CFDE_CSSCounterStyle {
209  public:
210   CFDE_CSSCounterStyle();
211   ~CFDE_CSSCounterStyle();
212 
SetCounterIncrementList(IFDE_CSSValueList * pList)213   void SetCounterIncrementList(IFDE_CSSValueList* pList) {
214     m_pCounterInc = pList;
215     m_bIndexDirty = TRUE;
216   }
SetCounterResetList(IFDE_CSSValueList * pList)217   void SetCounterResetList(IFDE_CSSValueList* pList) {
218     m_pCounterReset = pList;
219     m_bIndexDirty = TRUE;
220   }
CountCounters()221   int32_t CountCounters() {
222     UpdateIndex();
223     return m_arrCounterData.GetSize();
224   }
GetCounterIncrement(int32_t index,int32_t & iValue)225   FX_BOOL GetCounterIncrement(int32_t index, int32_t& iValue) {
226     UpdateIndex();
227     return m_arrCounterData.ElementAt(index).GetCounterIncrement(iValue);
228   }
GetCounterReset(int32_t index,int32_t & iValue)229   FX_BOOL GetCounterReset(int32_t index, int32_t& iValue) {
230     UpdateIndex();
231     return m_arrCounterData.ElementAt(index).GetCounterReset(iValue);
232   }
GetCounterIdentifier(int32_t index)233   const FX_WCHAR* GetCounterIdentifier(int32_t index) {
234     UpdateIndex();
235     return m_arrCounterData.ElementAt(index).m_pszIdent;
236   }
237 
238  protected:
239   void UpdateIndex();
240   void DoUpdateIndex(IFDE_CSSValueList* pList);
241   int32_t FindIndex(const FX_WCHAR* pszIdentifier);
242 
243   IFDE_CSSValueList* m_pCounterInc;
244   IFDE_CSSValueList* m_pCounterReset;
245   CFX_ArrayTemplate<FDE_CSSCOUNTERDATA> m_arrCounterData;
246   FX_BOOL m_bIndexDirty;
247 };
248 
249 class CFDE_CSSInheritedData {
250  public:
251   CFDE_CSSInheritedData();
252 
253   void Reset();
254 
255   const FX_WCHAR* m_pszListStyleImage;
256   FDE_CSSLENGTH m_LetterSpacing;
257   FDE_CSSLENGTH m_WordSpacing;
258   FDE_CSSLENGTH m_TextIndent;
259   IFDE_CSSValueList* m_pFontFamily;
260   IFDE_CSSValueList* m_pQuotes;
261   IFDE_CSSValueList* m_pCursorUris;
262   FDE_CSSCURSOR m_eCursor;
263   FX_FLOAT m_fFontSize;
264   FX_FLOAT m_fLineHeight;
265   FX_ARGB m_dwFontColor;
266   FX_ARGB m_dwTextEmphasisColor;
267   uint16_t m_wFontWeight;
268   int32_t m_iWidows;
269   int32_t m_iOrphans;
270   const FX_WCHAR* m_pszTextEmphasisCustomMark;
271   uint32_t m_eFontVariant : 1;
272   uint32_t m_eFontStyle : 1;
273   uint32_t m_bTextEmphasisColorCurrent : 1;
274   uint32_t m_eTextAligh : 2;
275   uint32_t m_eVisibility : 2;
276   uint32_t m_eWhiteSpace : 3;
277   uint32_t m_eTextTransform : 2;
278   uint32_t m_eWritingMode : 2;
279   uint32_t m_eWordBreak : 2;
280   uint32_t m_eLineBreak : 2;
281   uint32_t m_eTextEmphasisFill : 1;
282   uint32_t m_eTextEmphasisMark : 3;
283   uint32_t m_eCaptionSide : 3;
284   uint8_t m_eRubyAlign : 4;
285   uint8_t m_eRubyOverhang : 2;
286   uint8_t m_eRubyPosition : 2;
287 };
288 
289 class CFDE_CSSNonInheritedData {
290  public:
291   CFDE_CSSNonInheritedData();
292 
293   void Reset();
294 
295   IFDE_CSSValueList* m_pContentList;
296   CFDE_CSSCounterStyle* m_pCounterStyle;
297   FDE_CSSRECT m_MarginWidth;
298   FDE_CSSRECT m_BorderWidth;
299   FDE_CSSRECT m_PaddingWidth;
300   FDE_CSSSIZE m_BoxSize;
301   FDE_CSSSIZE m_MinBoxSize;
302   FDE_CSSSIZE m_MaxBoxSize;
303   FDE_CSSPOINT m_BKGPosition;
304   const FX_WCHAR* m_pszBKGImage;
305   FX_ARGB m_dwBKGColor;
306   FX_ARGB m_dwBDRLeftColor;
307   FX_ARGB m_dwBDRTopColor;
308   FX_ARGB m_dwBDRRightColor;
309   FX_ARGB m_dwBDRBottomColor;
310   IFDE_CSSValue* m_pRubySpan;
311   FDE_CSSLENGTH m_ColumnCount;
312   FDE_CSSLENGTH m_ColumnGap;
313   FDE_CSSLENGTH m_ColumnRuleWidth;
314   FDE_CSSLENGTH m_ColumnWidth;
315   FX_ARGB m_dwColumnRuleColor;
316   FDE_CSSLENGTH m_Top;
317   FDE_CSSLENGTH m_Bottom;
318   FDE_CSSLENGTH m_Left;
319   FDE_CSSLENGTH m_Right;
320 
321   FX_FLOAT m_fVerticalAlign;
322   FX_FLOAT m_fTextCombineNumber;
323   uint32_t m_eBDRLeftStyle : 4;
324   uint32_t m_eBDRTopStyle : 4;
325   uint32_t m_eBDRRightStyle : 4;
326   uint32_t m_eBDRBottomStyle : 4;
327   uint32_t m_eDisplay : 5;
328   uint32_t m_eVerticalAlign : 4;
329   uint32_t m_eListStyleType : 5;
330   uint32_t m_eColumnRuleStyle : 4;
331   uint32_t m_ePageBreakInside : 3;
332   uint32_t m_ePageBreakAfter : 3;
333   uint32_t m_ePageBreakBefore : 3;
334   uint32_t m_ePosition : 2;
335   uint32_t m_eBKGRepeat : 2;
336   uint32_t m_eFloat : 2;
337   uint32_t m_eClear : 2;
338   uint32_t m_eOverflowX : 3;
339   uint32_t m_eOverflowY : 3;
340   uint32_t m_eListStylePosition : 1;
341   uint32_t m_eBKGAttachment : 1;
342   uint32_t m_bHasMargin : 1;
343   uint32_t m_bHasBorder : 1;
344   uint32_t m_bHasPadding : 1;
345   uint32_t m_dwTextDecoration : 5;
346   uint32_t m_eTextCombine : 1;
347   uint32_t m_bColumnRuleColorSame : 1;
348   uint32_t m_bHasTextCombineNumber : 1;
349 };
350 
351 class CFDE_CSSComputedStyle : public IFDE_CSSComputedStyle,
352                               public IFDE_CSSBoundaryStyle,
353                               public IFDE_CSSFontStyle,
354                               public IFDE_CSSPositionStyle,
355                               public IFDE_CSSParagraphStyle,
356                               public CFX_Target {
357  public:
358   CFDE_CSSComputedStyle(IFX_MemoryAllocator* pAlloc);
359   ~CFDE_CSSComputedStyle() override;
360 
361   // IFX_Retainable
362   uint32_t Retain() override;
363   uint32_t Release() override;
364 
365   // IFDE_CSSComputedStyle
366   void Reset() override;
367   IFDE_CSSFontStyle* GetFontStyles() override;
368   IFDE_CSSBoundaryStyle* GetBoundaryStyles() override;
369   IFDE_CSSPositionStyle* GetPositionStyles() override;
370   IFDE_CSSParagraphStyle* GetParagraphStyles() override;
371   FX_BOOL GetCustomStyle(const CFX_WideStringC& wsName,
372                          CFX_WideString& wsValue) const override;
373 
374   // IFDE_CSSFontStyle:
375   int32_t CountFontFamilies() const override;
376   const FX_WCHAR* GetFontFamily(int32_t index) const override;
377   uint16_t GetFontWeight() const override;
378   FDE_CSSFONTVARIANT GetFontVariant() const override;
379   FDE_CSSFONTSTYLE GetFontStyle() const override;
380   FX_FLOAT GetFontSize() const override;
381   FX_ARGB GetColor() const override;
382   void SetFontWeight(uint16_t wFontWeight) override;
383   void SetFontVariant(FDE_CSSFONTVARIANT eFontVariant) override;
384   void SetFontStyle(FDE_CSSFONTSTYLE eFontStyle) override;
385   void SetFontSize(FX_FLOAT fFontSize) override;
386   void SetColor(FX_ARGB dwFontColor) override;
387 
388   // IFDE_CSSBoundaryStyle:
389   const FDE_CSSRECT* GetBorderWidth() const override;
390   const FDE_CSSRECT* GetMarginWidth() const override;
391   const FDE_CSSRECT* GetPaddingWidth() const override;
392   void SetMarginWidth(const FDE_CSSRECT& rect) override;
393   void SetPaddingWidth(const FDE_CSSRECT& rect) override;
394 
395   // IFDE_CSSPositionStyle:
396   FDE_CSSDISPLAY GetDisplay() const override;
397 
398   // IFDE_CSSParagraphStyle:
399   FX_FLOAT GetLineHeight() const override;
400   const FDE_CSSLENGTH& GetTextIndent() const override;
401   FDE_CSSTEXTALIGN GetTextAlign() const override;
402   FDE_CSSVERTICALALIGN GetVerticalAlign() const override;
403   FX_FLOAT GetNumberVerticalAlign() const override;
404   uint32_t GetTextDecoration() const override;
405   const FDE_CSSLENGTH& GetLetterSpacing() const override;
406   void SetLineHeight(FX_FLOAT fLineHeight) override;
407   void SetTextIndent(const FDE_CSSLENGTH& textIndent) override;
408   void SetTextAlign(FDE_CSSTEXTALIGN eTextAlign) override;
409   void SetNumberVerticalAlign(FX_FLOAT fAlign) override;
410   void SetTextDecoration(uint32_t dwTextDecoration) override;
411   void SetLetterSpacing(const FDE_CSSLENGTH& letterSpacing) override;
412   void AddCustomStyle(const CFX_WideString& wsName,
413                       const CFX_WideString& wsValue);
414 
415   uint32_t m_dwRefCount;
416   IFX_MemoryAllocator* m_pAllocator;
417   CFDE_CSSInheritedData m_InheritedData;
418   CFDE_CSSNonInheritedData m_NonInheritedData;
419   CFX_WideStringArray m_CustomProperties;
420 };
421 
422 #endif  // XFA_FDE_CSS_FDE_CSSSTYLESELECTOR_H_
423