layout/style/nsRuleNode.h

Wed, 31 Dec 2014 07:16:47 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 07:16:47 +0100
branch
TOR_BUG_9701
changeset 3
141e0f1194b1
permissions
-rw-r--r--

Revert simplistic fix pending revisit of Mozilla integration attempt.

     1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     2 /* This Source Code Form is subject to the terms of the Mozilla Public
     3  * License, v. 2.0. If a copy of the MPL was not distributed with this
     4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     6 /*
     7  * a node in the lexicographic tree of rules that match an element,
     8  * responsible for converting the rules' information into computed style
     9  */
    11 #ifndef nsRuleNode_h___
    12 #define nsRuleNode_h___
    14 #include "nsPresContext.h"
    15 #include "nsStyleStruct.h"
    17 #include <stdint.h>
    19 class nsStyleContext;
    20 struct nsRuleData;
    21 class nsIStyleRule;
    22 struct nsCSSValueList;
    24 class nsCSSValue;
    25 struct nsCSSRect;
    27 class nsStyleCoord;
    28 struct nsCSSValuePairList;
    30 template <nsStyleStructID MinIndex, nsStyleStructID Count>
    31 class FixedStyleStructArray
    32 {
    33 private:
    34   void* mArray[Count];
    35 public:
    36   void*& operator[](nsStyleStructID aIndex) {
    37     NS_ABORT_IF_FALSE(MinIndex <= aIndex && aIndex < (MinIndex + Count),
    38                       "out of range");
    39     return mArray[aIndex - MinIndex];
    40   }
    42   const void* operator[](nsStyleStructID aIndex) const {
    43     NS_ABORT_IF_FALSE(MinIndex <= aIndex && aIndex < (MinIndex + Count),
    44                       "out of range");
    45     return mArray[aIndex - MinIndex];
    46   }
    47 };
    49 struct nsInheritedStyleData
    50 {
    51   FixedStyleStructArray<nsStyleStructID_Inherited_Start,
    52                         nsStyleStructID_Inherited_Count> mStyleStructs;
    54   void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
    55     return aContext->AllocateFromShell(sz);
    56   }
    58   void DestroyStructs(uint64_t aBits, nsPresContext* aContext) {
    59 #define STYLE_STRUCT_INHERITED(name, checkdata_cb) \
    60     void *name##Data = mStyleStructs[eStyleStruct_##name]; \
    61     if (name##Data && !(aBits & NS_STYLE_INHERIT_BIT(name))) \
    62       static_cast<nsStyle##name*>(name##Data)->Destroy(aContext);
    63 #define STYLE_STRUCT_RESET(name, checkdata_cb)
    65 #include "nsStyleStructList.h"
    67 #undef STYLE_STRUCT_INHERITED
    68 #undef STYLE_STRUCT_RESET
    69   }
    71   void Destroy(uint64_t aBits, nsPresContext* aContext) {
    72     DestroyStructs(aBits, aContext);
    73     aContext->FreeToShell(sizeof(nsInheritedStyleData), this);
    74   }
    76   nsInheritedStyleData() {
    77     for (nsStyleStructID i = nsStyleStructID_Inherited_Start;
    78          i < nsStyleStructID_Inherited_Start + nsStyleStructID_Inherited_Count;
    79          i = nsStyleStructID(i + 1)) {
    80       mStyleStructs[i] = nullptr;
    81     }
    82   }
    83 };
    85 struct nsResetStyleData
    86 {
    87   FixedStyleStructArray<nsStyleStructID_Reset_Start,
    88                         nsStyleStructID_Reset_Count> mStyleStructs;
    90   nsResetStyleData()
    91   {
    92     for (nsStyleStructID i = nsStyleStructID_Reset_Start;
    93          i < nsStyleStructID_Reset_Start + nsStyleStructID_Reset_Count;
    94          i = nsStyleStructID(i + 1)) {
    95       mStyleStructs[i] = nullptr;
    96     }
    97   }
    99   void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
   100     return aContext->AllocateFromShell(sz);
   101   }
   103   void Destroy(uint64_t aBits, nsPresContext* aContext) {
   104 #define STYLE_STRUCT_RESET(name, checkdata_cb) \
   105     void *name##Data = mStyleStructs[eStyleStruct_##name]; \
   106     if (name##Data && !(aBits & NS_STYLE_INHERIT_BIT(name))) \
   107       static_cast<nsStyle##name*>(name##Data)->Destroy(aContext);
   108 #define STYLE_STRUCT_INHERITED(name, checkdata_cb)
   110 #include "nsStyleStructList.h"
   112 #undef STYLE_STRUCT_RESET
   113 #undef STYLE_STRUCT_INHERITED
   115     aContext->FreeToShell(sizeof(nsResetStyleData), this);
   116   }
   117 };
   119 struct nsCachedStyleData
   120 {
   121   nsInheritedStyleData* mInheritedData;
   122   nsResetStyleData* mResetData;
   124   static bool IsReset(const nsStyleStructID aSID) {
   125     NS_ABORT_IF_FALSE(0 <= aSID && aSID < nsStyleStructID_Length,
   126                       "must be an inherited or reset SID");
   127     return nsStyleStructID_Reset_Start <= aSID;
   128   }
   130   static bool IsInherited(const nsStyleStructID aSID) {
   131     return !IsReset(aSID);
   132   }
   134   static uint32_t GetBitForSID(const nsStyleStructID aSID) {
   135     return 1 << aSID;
   136   }
   138   void* NS_FASTCALL GetStyleData(const nsStyleStructID aSID) {
   139     if (IsReset(aSID)) {
   140       if (mResetData) {
   141         return mResetData->mStyleStructs[aSID];
   142       }
   143     } else {
   144       if (mInheritedData) {
   145         return mInheritedData->mStyleStructs[aSID];
   146       }
   147     }
   148     return nullptr;
   149   }
   151   void NS_FASTCALL SetStyleData(const nsStyleStructID aSID,
   152                                 nsPresContext *aPresContext, void *aData) {
   153     if (IsReset(aSID)) {
   154       if (!mResetData) {
   155         mResetData = new (aPresContext) nsResetStyleData;
   156       }
   157       mResetData->mStyleStructs[aSID] = aData;
   158     } else {
   159       if (!mInheritedData) {
   160         mInheritedData = new (aPresContext) nsInheritedStyleData;
   161       }
   162       mInheritedData->mStyleStructs[aSID] = aData;
   163     }
   164   }
   166   // Typesafe and faster versions of the above
   167   #define STYLE_STRUCT_INHERITED(name_, checkdata_cb_)                   \
   168     nsStyle##name_ * NS_FASTCALL GetStyle##name_ () {                    \
   169       return mInheritedData ? static_cast<nsStyle##name_*>(              \
   170         mInheritedData->mStyleStructs[eStyleStruct_##name_]) : nullptr;  \
   171     }
   172   #define STYLE_STRUCT_RESET(name_, checkdata_cb_)                       \
   173     nsStyle##name_ * NS_FASTCALL GetStyle##name_ () {                    \
   174       return mResetData ? static_cast<nsStyle##name_*>(                  \
   175         mResetData->mStyleStructs[eStyleStruct_##name_]) : nullptr;      \
   176     }
   177   #include "nsStyleStructList.h"
   178   #undef STYLE_STRUCT_RESET
   179   #undef STYLE_STRUCT_INHERITED
   181   void Destroy(uint64_t aBits, nsPresContext* aContext) {
   182     if (mResetData)
   183       mResetData->Destroy(aBits, aContext);
   184     if (mInheritedData)
   185       mInheritedData->Destroy(aBits, aContext);
   186     mResetData = nullptr;
   187     mInheritedData = nullptr;
   188   }
   190   nsCachedStyleData() :mInheritedData(nullptr), mResetData(nullptr) {}
   191   ~nsCachedStyleData() {}
   192 };
   194 /**
   195  * nsRuleNode is a node in a lexicographic tree (the "rule tree")
   196  * indexed by style rules (implementations of nsIStyleRule).
   197  *
   198  * The rule tree is owned by the nsStyleSet and is destroyed when the
   199  * presentation of the document goes away.  It is garbage-collected
   200  * (using mark-and-sweep garbage collection) during the lifetime of the
   201  * document (when dynamic changes cause the destruction of enough style
   202  * contexts).  Rule nodes are marked if they are pointed to by a style
   203  * context or one of their descendants is.
   204  *
   205  * An nsStyleContext, which represents the computed style data for an
   206  * element, points to an nsRuleNode.  The path from the root of the rule
   207  * tree to the nsStyleContext's mRuleNode gives the list of the rules
   208  * matched, from least important in the cascading order to most
   209  * important in the cascading order.
   210  *
   211  * The reason for using a lexicographic tree is that it allows for
   212  * sharing of style data, which saves both memory (for storing the
   213  * computed style data) and time (for computing them).  This sharing
   214  * depends on the computed style data being stored in structs (nsStyle*)
   215  * that contain only properties that are inherited by default
   216  * ("inherited structs") or structs that contain only properties that
   217  * are not inherited by default ("reset structs").  The optimization
   218  * depends on the normal case being that style rules specify relatively
   219  * few properties and even that elements generally have relatively few
   220  * properties specified.  This allows sharing in the following ways:
   221  *   1. [mainly reset structs] When a style data struct will contain the
   222  *      same computed value for any elements that match the same set of
   223  *      rules (common for reset structs), it can be stored on the
   224  *      nsRuleNode instead of on the nsStyleContext.
   225  *   2. [only? reset structs] When (1) occurs, and an nsRuleNode doesn't
   226  *      have any rules that change the values in the struct, the
   227  *      nsRuleNode can share that struct with its parent nsRuleNode.
   228  *   3. [mainly inherited structs] When an element doesn't match any
   229  *      rules that change the value of a property (or, in the edge case,
   230  *      when all the values specified are 'inherit'), the nsStyleContext
   231  *      can use the same nsStyle* struct as its parent nsStyleContext.
   232  *
   233  * Since the data represented by an nsIStyleRule are immutable, the data
   234  * represented by an nsRuleNode are also immutable.
   235  */
   237 enum nsFontSizeType {
   238   eFontSize_HTML = 1,
   239   eFontSize_CSS = 2
   240 };
   242 class nsRuleNode {
   243 public:
   244   enum RuleDetail {
   245     eRuleNone, // No props have been specified at all.
   246     eRulePartialReset, // At least one prop with a non-"inherit" value
   247                        // has been specified.  No props have been
   248                        // specified with an "inherit" value.  At least
   249                        // one prop remains unspecified.
   250     eRulePartialMixed, // At least one prop with a non-"inherit" value
   251                        // has been specified.  Some props may also have
   252                        // been specified with an "inherit" value.  At
   253                        // least one prop remains unspecified.
   254     eRulePartialInherited, // Only props with "inherit" values have
   255                            // have been specified.  At least one prop
   256                            // remains unspecified.
   257     eRuleFullReset, // All props have been specified.  None has an
   258                     // "inherit" value.
   259     eRuleFullMixed, // All props have been specified.  At least one has
   260                     // a non-"inherit" value.
   261     eRuleFullInherited  // All props have been specified with "inherit"
   262                         // values.
   263   };
   265 private:
   266   nsPresContext* const mPresContext; // Our pres context.
   268   nsRuleNode* const mParent; // A pointer to the parent node in the tree.
   269                              // This enables us to walk backwards from the
   270                              // most specific rule matched to the least
   271                              // specific rule (which is the optimal order to
   272                              // use for lookups of style properties.
   273   nsIStyleRule* const mRule; // [STRONG] A pointer to our specific rule.
   275   nsRuleNode* mNextSibling; // This value should be used only by the
   276                             // parent, since the parent may store
   277                             // children in a hash, which means this
   278                             // pointer is not meaningful.  Order of
   279                             // siblings is also not meaningful.
   281   struct Key {
   282     nsIStyleRule* mRule;
   283     uint8_t mLevel;
   284     bool mIsImportantRule;
   286     Key(nsIStyleRule* aRule, uint8_t aLevel, bool aIsImportantRule)
   287       : mRule(aRule), mLevel(aLevel), mIsImportantRule(aIsImportantRule)
   288     {}
   290     bool operator==(const Key& aOther) const
   291     {
   292       return mRule == aOther.mRule &&
   293              mLevel == aOther.mLevel &&
   294              mIsImportantRule == aOther.mIsImportantRule;
   295     }
   297     bool operator!=(const Key& aOther) const
   298     {
   299       return !(*this == aOther);
   300     }
   301   };
   303   static PLDHashNumber
   304   ChildrenHashHashKey(PLDHashTable *aTable, const void *aKey);
   306   static bool
   307   ChildrenHashMatchEntry(PLDHashTable *aTable,
   308                          const PLDHashEntryHdr *aHdr,
   309                          const void *aKey);
   311   static const PLDHashTableOps ChildrenHashOps;
   313   static PLDHashOperator
   314   EnqueueRuleNodeChildren(PLDHashTable *table, PLDHashEntryHdr *hdr,
   315                           uint32_t number, void *arg);
   317   Key GetKey() const {
   318     return Key(mRule, GetLevel(), IsImportantRule());
   319   }
   321   // The children of this node are stored in either a hashtable or list
   322   // that maps from rules to our nsRuleNode children.  When matching
   323   // rules, we use this mapping to transition from node to node
   324   // (constructing new nodes as needed to flesh out the tree).
   326   union {
   327     void* asVoid;
   328     nsRuleNode* asList;
   329     PLDHashTable* asHash;
   330   } mChildren; // Accessed only through the methods below.
   332   enum {
   333     kTypeMask = 0x1,
   334     kListType = 0x0,
   335     kHashType = 0x1
   336   };
   337   enum {
   338     // Maximum to have in a list before converting to a hashtable.
   339     // XXX Need to optimize this.
   340     kMaxChildrenInList = 32
   341   };
   343   bool HaveChildren() const {
   344     return mChildren.asVoid != nullptr;
   345   }
   346   bool ChildrenAreHashed() {
   347     return (intptr_t(mChildren.asVoid) & kTypeMask) == kHashType;
   348   }
   349   nsRuleNode* ChildrenList() {
   350     return mChildren.asList;
   351   }
   352   nsRuleNode** ChildrenListPtr() {
   353     return &mChildren.asList;
   354   }
   355   PLDHashTable* ChildrenHash() {
   356     return (PLDHashTable*) (intptr_t(mChildren.asHash) & ~intptr_t(kTypeMask));
   357   }
   358   void SetChildrenList(nsRuleNode *aList) {
   359     NS_ASSERTION(!(intptr_t(aList) & kTypeMask),
   360                  "pointer not 2-byte aligned");
   361     mChildren.asList = aList;
   362   }
   363   void SetChildrenHash(PLDHashTable *aHashtable) {
   364     NS_ASSERTION(!(intptr_t(aHashtable) & kTypeMask),
   365                  "pointer not 2-byte aligned");
   366     mChildren.asHash = (PLDHashTable*)(intptr_t(aHashtable) | kHashType);
   367   }
   368   void ConvertChildrenToHash();
   370   nsCachedStyleData mStyleData;   // Any data we cached on the rule node.
   372   uint32_t mDependentBits; // Used to cache the fact that we can look up
   373                            // cached data under a parent rule.
   375   uint32_t mNoneBits; // Used to cache the fact that the branch to this
   376                       // node specifies no non-inherited data for a
   377                       // given struct type.  (This usually implies that
   378                       // the entire branch specifies no non-inherited
   379                       // data, although not necessarily, if a
   380                       // non-inherited value is overridden by an
   381                       // explicit 'inherit' value.)  For example, if an
   382                       // entire rule branch specifies no color
   383                       // information, then a bit will be set along every
   384                       // rule node on that branch, so that you can break
   385                       // out of the rule tree early and just inherit
   386                       // from the parent style context.  The presence of
   387                       // this bit means we should just get inherited
   388                       // data from the parent style context, and it is
   389                       // never used for reset structs since their
   390                       // Compute*Data functions don't initialize from
   391                       // inherited data.
   393   // Reference count.  This just counts the style contexts that reference this
   394   // rulenode.  And children the rulenode has had.  When this goes to 0 or
   395   // stops being 0, we notify the style set.
   396   // Note, in particular, that when a child is removed mRefCnt is NOT
   397   // decremented.  This is on purpose; the notifications to the style set are
   398   // only used to determine when it's worth running GC on the ruletree, and
   399   // this setup makes it so we only count unused ruletree leaves for purposes
   400   // of deciding when to GC.  We could more accurately count unused rulenodes
   401   // by releasing/addrefing our parent when our refcount transitions to or from
   402   // 0, but it doesn't seem worth it to do that.
   403   uint32_t mRefCnt;
   405 public:
   406   // Overloaded new operator. Initializes the memory to 0 and relies on an arena
   407   // (which comes from the presShell) to perform the allocation.
   408   void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW;
   409   void Destroy() { DestroyInternal(nullptr); }
   411   // Implemented in nsStyleSet.h, since it needs to know about nsStyleSet.
   412   inline void AddRef();
   414   // Implemented in nsStyleSet.h, since it needs to know about nsStyleSet.
   415   inline void Release();
   417 protected:
   418   void DestroyInternal(nsRuleNode ***aDestroyQueueTail);
   419   void PropagateDependentBit(nsStyleStructID aSID, nsRuleNode* aHighestNode,
   420                              void* aStruct);
   421   void PropagateNoneBit(uint32_t aBit, nsRuleNode* aHighestNode);
   423   const void* SetDefaultOnRoot(const nsStyleStructID aSID,
   424                                nsStyleContext* aContext);
   426   /**
   427    * Resolves any property values in aRuleData for a given style struct that
   428    * have eCSSUnit_TokenStream values, by resolving them against the computed
   429    * variable values on the style context and re-parsing the property.
   430    *
   431    * @return Whether any properties with eCSSUnit_TokenStream values were
   432    *   encountered.
   433    */
   434   static bool ResolveVariableReferences(const nsStyleStructID aSID,
   435                                         nsRuleData* aRuleData,
   436                                         nsStyleContext* aContext);
   438   const void*
   439     WalkRuleTree(const nsStyleStructID aSID, nsStyleContext* aContext);
   441   const void*
   442     ComputeDisplayData(void* aStartStruct,
   443                        const nsRuleData* aRuleData,
   444                        nsStyleContext* aContext, nsRuleNode* aHighestNode,
   445                        RuleDetail aRuleDetail,
   446                        const bool aCanStoreInRuleTree);
   448   const void*
   449     ComputeVisibilityData(void* aStartStruct,
   450                           const nsRuleData* aRuleData,
   451                           nsStyleContext* aContext, nsRuleNode* aHighestNode,
   452                           RuleDetail aRuleDetail,
   453                           const bool aCanStoreInRuleTree);
   455   const void*
   456     ComputeFontData(void* aStartStruct,
   457                     const nsRuleData* aRuleData,
   458                     nsStyleContext* aContext, nsRuleNode* aHighestNode,
   459                     RuleDetail aRuleDetail,
   460                     const bool aCanStoreInRuleTree);
   462   const void*
   463     ComputeColorData(void* aStartStruct,
   464                      const nsRuleData* aRuleData,
   465                      nsStyleContext* aContext, nsRuleNode* aHighestNode,
   466                      RuleDetail aRuleDetail,
   467                      const bool aCanStoreInRuleTree);
   469   const void*
   470     ComputeBackgroundData(void* aStartStruct,
   471                           const nsRuleData* aRuleData,
   472                           nsStyleContext* aContext, nsRuleNode* aHighestNode,
   473                           RuleDetail aRuleDetail,
   474                           const bool aCanStoreInRuleTree);
   476   const void*
   477     ComputeMarginData(void* aStartStruct,
   478                       const nsRuleData* aRuleData,
   479                       nsStyleContext* aContext, nsRuleNode* aHighestNode,
   480                       RuleDetail aRuleDetail,
   481                       const bool aCanStoreInRuleTree);
   483   const void*
   484     ComputeBorderData(void* aStartStruct,
   485                       const nsRuleData* aRuleData,
   486                       nsStyleContext* aContext, nsRuleNode* aHighestNode,
   487                       RuleDetail aRuleDetail,
   488                       const bool aCanStoreInRuleTree);
   490   const void*
   491     ComputePaddingData(void* aStartStruct,
   492                        const nsRuleData* aRuleData,
   493                        nsStyleContext* aContext, nsRuleNode* aHighestNode,
   494                        RuleDetail aRuleDetail,
   495                        const bool aCanStoreInRuleTree);
   497   const void*
   498     ComputeOutlineData(void* aStartStruct,
   499                        const nsRuleData* aRuleData,
   500                        nsStyleContext* aContext, nsRuleNode* aHighestNode,
   501                        RuleDetail aRuleDetail,
   502                        const bool aCanStoreInRuleTree);
   504   const void*
   505     ComputeListData(void* aStartStruct,
   506                     const nsRuleData* aRuleData,
   507                     nsStyleContext* aContext, nsRuleNode* aHighestNode,
   508                     RuleDetail aRuleDetail,
   509                     const bool aCanStoreInRuleTree);
   511   const void*
   512     ComputePositionData(void* aStartStruct,
   513                         const nsRuleData* aRuleData,
   514                         nsStyleContext* aContext, nsRuleNode* aHighestNode,
   515                         RuleDetail aRuleDetail,
   516                         const bool aCanStoreInRuleTree);
   518   const void*
   519     ComputeTableData(void* aStartStruct,
   520                      const nsRuleData* aRuleData,
   521                      nsStyleContext* aContext, nsRuleNode* aHighestNode,
   522                      RuleDetail aRuleDetail,
   523                      const bool aCanStoreInRuleTree);
   525   const void*
   526     ComputeTableBorderData(void* aStartStruct,
   527                            const nsRuleData* aRuleData,
   528                            nsStyleContext* aContext, nsRuleNode* aHighestNode,
   529                            RuleDetail aRuleDetail,
   530                            const bool aCanStoreInRuleTree);
   532   const void*
   533     ComputeContentData(void* aStartStruct,
   534                        const nsRuleData* aRuleData,
   535                        nsStyleContext* aContext, nsRuleNode* aHighestNode,
   536                        RuleDetail aRuleDetail,
   537                        const bool aCanStoreInRuleTree);
   539   const void*
   540     ComputeQuotesData(void* aStartStruct,
   541                       const nsRuleData* aRuleData,
   542                       nsStyleContext* aContext, nsRuleNode* aHighestNode,
   543                       RuleDetail aRuleDetail,
   544                       const bool aCanStoreInRuleTree);
   546   const void*
   547     ComputeTextData(void* aStartStruct,
   548                     const nsRuleData* aRuleData,
   549                     nsStyleContext* aContext, nsRuleNode* aHighestNode,
   550                     RuleDetail aRuleDetail,
   551                     const bool aCanStoreInRuleTree);
   553   const void*
   554     ComputeTextResetData(void* aStartStruct,
   555                          const nsRuleData* aRuleData,
   556                          nsStyleContext* aContext, nsRuleNode* aHighestNode,
   557                          RuleDetail aRuleDetail,
   558                          const bool aCanStoreInRuleTree);
   560   const void*
   561     ComputeUserInterfaceData(void* aStartStruct,
   562                              const nsRuleData* aRuleData,
   563                              nsStyleContext* aContext,
   564                              nsRuleNode* aHighestNode,
   565                              RuleDetail aRuleDetail,
   566                              const bool aCanStoreInRuleTree);
   568   const void*
   569     ComputeUIResetData(void* aStartStruct,
   570                        const nsRuleData* aRuleData,
   571                        nsStyleContext* aContext, nsRuleNode* aHighestNode,
   572                        RuleDetail aRuleDetail,
   573                        const bool aCanStoreInRuleTree);
   575   const void*
   576     ComputeXULData(void* aStartStruct,
   577                    const nsRuleData* aRuleData,
   578                    nsStyleContext* aContext, nsRuleNode* aHighestNode,
   579                    RuleDetail aRuleDetail,
   580                    const bool aCanStoreInRuleTree);
   582   const void*
   583     ComputeColumnData(void* aStartStruct,
   584                       const nsRuleData* aRuleData,
   585                       nsStyleContext* aContext, nsRuleNode* aHighestNode,
   586                       RuleDetail aRuleDetail,
   587                       const bool aCanStoreInRuleTree);
   589   const void*
   590     ComputeSVGData(void* aStartStruct,
   591                    const nsRuleData* aRuleData,
   592                    nsStyleContext* aContext, nsRuleNode* aHighestNode,
   593                    RuleDetail aRuleDetail,
   594                    const bool aCanStoreInRuleTree);
   596   const void*
   597     ComputeSVGResetData(void* aStartStruct,
   598                         const nsRuleData* aRuleData,
   599                         nsStyleContext* aContext, nsRuleNode* aHighestNode,
   600                         RuleDetail aRuleDetail,
   601                         const bool aCanStoreInRuleTree);
   603   const void*
   604     ComputeVariablesData(void* aStartStruct,
   605                          const nsRuleData* aRuleData,
   606                          nsStyleContext* aContext, nsRuleNode* aHighestNode,
   607                          RuleDetail aRuleDetail,
   608                          const bool aCanStoreInRuleTree);
   610   // helpers for |ComputeFontData| that need access to |mNoneBits|:
   611   static void SetFontSize(nsPresContext* aPresContext,
   612                           const nsRuleData* aRuleData,
   613                           const nsStyleFont* aFont,
   614                           const nsStyleFont* aParentFont,
   615                           nscoord* aSize,
   616                           const nsFont& aSystemFont,
   617                           nscoord aParentSize,
   618                           nscoord aScriptLevelAdjustedParentSize,
   619                           bool aUsedStartStruct,
   620                           bool aAtRoot,
   621                           bool& aCanStoreInRuleTree);
   623   static void SetFont(nsPresContext* aPresContext,
   624                       nsStyleContext* aContext,
   625                       uint8_t aGenericFontID,
   626                       const nsRuleData* aRuleData,
   627                       const nsStyleFont* aParentFont,
   628                       nsStyleFont* aFont,
   629                       bool aStartStruct,
   630                       bool& aCanStoreInRuleTree);
   632   static void SetGenericFont(nsPresContext* aPresContext,
   633                              nsStyleContext* aContext,
   634                              uint8_t aGenericFontID,
   635                              nsStyleFont* aFont);
   637   void AdjustLogicalBoxProp(nsStyleContext* aContext,
   638                             const nsCSSValue& aLTRSource,
   639                             const nsCSSValue& aRTLSource,
   640                             const nsCSSValue& aLTRLogicalValue,
   641                             const nsCSSValue& aRTLLogicalValue,
   642                             mozilla::css::Side aSide,
   643                             nsCSSRect& aValueRect,
   644                             bool& aCanStoreInRuleTree);
   646   inline RuleDetail CheckSpecifiedProperties(const nsStyleStructID aSID,
   647                                              const nsRuleData* aRuleData);
   649   already_AddRefed<nsCSSShadowArray>
   650               GetShadowData(const nsCSSValueList* aList,
   651                             nsStyleContext* aContext,
   652                             bool aIsBoxShadow,
   653                             bool& aCanStoreInRuleTree);
   654   bool SetStyleFilterToCSSValue(nsStyleFilter* aStyleFilter,
   655                                 const nsCSSValue& aValue,
   656                                 nsStyleContext* aStyleContext,
   657                                 nsPresContext* aPresContext,
   658                                 bool& aCanStoreInRuleTree);
   660 private:
   661   nsRuleNode(nsPresContext* aPresContext, nsRuleNode* aParent,
   662              nsIStyleRule* aRule, uint8_t aLevel, bool aIsImportant);
   663   ~nsRuleNode();
   665 public:
   666   static nsRuleNode* CreateRootNode(nsPresContext* aPresContext);
   668   static void EnsureBlockDisplay(uint8_t& display,
   669                                  bool aConvertListItem = false);
   671   // Transition never returns null; on out of memory it'll just return |this|.
   672   nsRuleNode* Transition(nsIStyleRule* aRule, uint8_t aLevel,
   673                          bool aIsImportantRule);
   674   nsRuleNode* GetParent() const { return mParent; }
   675   bool IsRoot() const { return mParent == nullptr; }
   677   // These uint8_ts are really nsStyleSet::sheetType values.
   678   uint8_t GetLevel() const {
   679     NS_ASSERTION(!IsRoot(), "can't call on root");
   680     return (mDependentBits & NS_RULE_NODE_LEVEL_MASK) >>
   681              NS_RULE_NODE_LEVEL_SHIFT;
   682   }
   683   bool IsImportantRule() const {
   684     NS_ASSERTION(!IsRoot(), "can't call on root");
   685     return (mDependentBits & NS_RULE_NODE_IS_IMPORTANT) != 0;
   686   }
   688   /**
   689    * Has this rule node at some time in its lifetime been the mRuleNode
   690    * of some style context (as opposed to only being the ancestor of
   691    * some style context's mRuleNode)?
   692    */
   693   void SetUsedDirectly();
   694   bool IsUsedDirectly() const {
   695     return (mDependentBits & NS_RULE_NODE_USED_DIRECTLY) != 0;
   696   }
   698   // NOTE:  Does not |AddRef|.  Null only for the root.
   699   nsIStyleRule* GetRule() const { return mRule; }
   700   // NOTE: Does not |AddRef|.  Never null.
   701   nsPresContext* PresContext() const { return mPresContext; }
   703   const void* GetStyleData(nsStyleStructID aSID,
   704                            nsStyleContext* aContext,
   705                            bool aComputeData);
   707   #define STYLE_STRUCT(name_, checkdata_cb_)                                  \
   708     const nsStyle##name_* GetStyle##name_(nsStyleContext* aContext,           \
   709                                           bool aComputeData);
   710   #include "nsStyleStructList.h"
   711   #undef STYLE_STRUCT
   713   /*
   714    * Garbage collection.  Mark walks up the tree, marking any unmarked
   715    * ancestors until it reaches a marked one.  Sweep recursively sweeps
   716    * the children, destroys any that are unmarked, and clears marks,
   717    * returning true if the node on which it was called was destroyed.
   718    */
   719   void Mark();
   720   bool Sweep();
   722   static bool
   723     HasAuthorSpecifiedRules(nsStyleContext* aStyleContext,
   724                             uint32_t ruleTypeMask,
   725                             bool aAuthorColorsAllowed);
   727   // Expose this so media queries can use it
   728   static nscoord CalcLengthWithInitialFont(nsPresContext* aPresContext,
   729                                            const nsCSSValue& aValue);
   730   // Expose this so nsTransformFunctions can use it.
   731   static nscoord CalcLength(const nsCSSValue& aValue,
   732                             nsStyleContext* aStyleContext,
   733                             nsPresContext* aPresContext,
   734                             bool& aCanStoreInRuleTree);
   736   struct ComputedCalc {
   737     nscoord mLength;
   738     float mPercent;
   740     ComputedCalc(nscoord aLength, float aPercent)
   741       : mLength(aLength), mPercent(aPercent) {}
   742   };
   743   static ComputedCalc
   744   SpecifiedCalcToComputedCalc(const nsCSSValue& aValue,
   745                               nsStyleContext* aStyleContext,
   746                               nsPresContext* aPresContext,
   747                               bool& aCanStoreInRuleTree);
   749   // Compute the value of an nsStyleCoord that IsCalcUnit().
   750   // (Values that don't require aPercentageBasis should be handled
   751   // inside nsRuleNode rather than through this API.)
   752   static nscoord ComputeComputedCalc(const nsStyleCoord& aCoord,
   753                                      nscoord aPercentageBasis);
   755   // Compute the value of an nsStyleCoord that is either a coord, a
   756   // percent, or a calc expression.
   757   static nscoord ComputeCoordPercentCalc(const nsStyleCoord& aCoord,
   758                                          nscoord aPercentageBasis);
   760   // Return whether the rule tree for which this node is the root has
   761   // cached data such that we need to do dynamic change handling for
   762   // changes that change the results of media queries or require
   763   // rebuilding all style data.
   764   bool TreeHasCachedData() const {
   765     NS_ASSERTION(IsRoot(), "should only be called on root of rule tree");
   766     return HaveChildren() || mStyleData.mInheritedData || mStyleData.mResetData;
   767   }
   769   bool NodeHasCachedData(const nsStyleStructID aSID) {
   770     return !!mStyleData.GetStyleData(aSID);
   771   }
   773   static void ComputeFontFeatures(const nsCSSValuePairList *aFeaturesList,
   774                                   nsTArray<gfxFontFeature>& aFeatureSettings);
   776   static nscoord CalcFontPointSize(int32_t aHTMLSize, int32_t aBasePointSize, 
   777                                    nsPresContext* aPresContext,
   778                                    nsFontSizeType aFontSizeType = eFontSize_HTML);
   780   static nscoord FindNextSmallerFontSize(nscoord aFontSize, int32_t aBasePointSize, 
   781                                          nsPresContext* aPresContext,
   782                                          nsFontSizeType aFontSizeType = eFontSize_HTML);
   784   static nscoord FindNextLargerFontSize(nscoord aFontSize, int32_t aBasePointSize, 
   785                                         nsPresContext* aPresContext,
   786                                         nsFontSizeType aFontSizeType = eFontSize_HTML);
   788   /**
   789    * @param aValue The color value, returned from nsCSSParser::ParseColorString
   790    * @param aPresContext Presentation context whose preferences are used
   791    *                     for certain enumerated colors
   792    * @param aStyleContext Style context whose color is used for 'currentColor'
   793    *
   794    * @note aPresContext and aStyleContext may be null, but in that case, fully
   795    *       opaque black will be returned for the values that rely on these
   796    *       objects to compute the color. (For example, -moz-hyperlinktext.)
   797    *
   798    * @return false if we fail to extract a color; this will not happen if both
   799    *         aPresContext and aStyleContext are non-null
   800    */
   801   static bool ComputeColor(const nsCSSValue& aValue,
   802                            nsPresContext* aPresContext,
   803                            nsStyleContext* aStyleContext,
   804                            nscolor& aResult);
   805 };
   807 #endif

mercurial