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