michael@0: /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: /* michael@0: * temporary (expanded) representation of property-value pairs used to michael@0: * hold data from matched rules during style data computation. michael@0: */ michael@0: michael@0: #ifndef nsRuleData_h_ michael@0: #define nsRuleData_h_ michael@0: michael@0: #include "mozilla/CSSVariableDeclarations.h" michael@0: #include "nsCSSProps.h" michael@0: #include "nsCSSValue.h" michael@0: #include "nsStyleStructFwd.h" michael@0: michael@0: class nsPresContext; michael@0: class nsStyleContext; michael@0: struct nsRuleData; michael@0: michael@0: typedef void (*nsPostResolveFunc)(void* aStyleStruct, nsRuleData* aData); michael@0: michael@0: struct nsRuleData michael@0: { michael@0: const uint32_t mSIDs; michael@0: bool mCanStoreInRuleTree; michael@0: bool mIsImportantRule; michael@0: uint16_t mLevel; // an nsStyleSet::sheetType michael@0: nsPresContext* const mPresContext; michael@0: nsStyleContext* const mStyleContext; michael@0: michael@0: // We store nsCSSValues needed to compute the data for one or more michael@0: // style structs (specified by the bitfield mSIDs). These are stored michael@0: // in a single array allocation (which our caller allocates; see michael@0: // AutoCSSValueArray) The offset of each property |prop| in michael@0: // mValueStorage is the sum of michael@0: // mValueOffsets[nsCSSProps::kSIDTable[prop]] and michael@0: // nsCSSProps::PropertyIndexInStruct(prop). The only place we gather michael@0: // more than one style struct's data at a time is michael@0: // nsRuleNode::HasAuthorSpecifiedRules; therefore some code that we michael@0: // know is not called from HasAuthorSpecifiedRules assumes that the michael@0: // mValueOffsets for the one struct in mSIDs is zero. michael@0: nsCSSValue* const mValueStorage; // our user owns this array michael@0: size_t mValueOffsets[nsStyleStructID_Length]; michael@0: michael@0: nsAutoPtr mVariables; michael@0: michael@0: nsRuleData(uint32_t aSIDs, nsCSSValue* aValueStorage, michael@0: nsPresContext* aContext, nsStyleContext* aStyleContext); michael@0: michael@0: #ifdef DEBUG michael@0: ~nsRuleData(); michael@0: #else michael@0: ~nsRuleData() {} michael@0: #endif michael@0: michael@0: /** michael@0: * Return a pointer to the value object within |this| corresponding michael@0: * to property |aProperty|. michael@0: * michael@0: * This function must only be called if the given property is in michael@0: * mSIDs. michael@0: */ michael@0: nsCSSValue* ValueFor(nsCSSProperty aProperty) michael@0: { michael@0: NS_ABORT_IF_FALSE(aProperty < eCSSProperty_COUNT_no_shorthands, michael@0: "invalid or shorthand property"); michael@0: michael@0: nsStyleStructID sid = nsCSSProps::kSIDTable[aProperty]; michael@0: size_t indexInStruct = nsCSSProps::PropertyIndexInStruct(aProperty); michael@0: michael@0: // This should really be nsCachedStyleData::GetBitForSID, but we can't michael@0: // include that here since it includes us. michael@0: NS_ABORT_IF_FALSE(mSIDs & (1 << sid), michael@0: "calling nsRuleData::ValueFor on property not in mSIDs"); michael@0: NS_ABORT_IF_FALSE(sid != eStyleStruct_BackendOnly && michael@0: indexInStruct != size_t(-1), michael@0: "backend-only property"); michael@0: michael@0: return mValueStorage + mValueOffsets[sid] + indexInStruct; michael@0: } michael@0: michael@0: const nsCSSValue* ValueFor(nsCSSProperty aProperty) const { michael@0: return const_cast(this)->ValueFor(aProperty); michael@0: } michael@0: michael@0: /** michael@0: * Getters like ValueFor(aProperty), but for each property by name michael@0: * (ValueForBackgroundColor, etc.), and more efficient than ValueFor. michael@0: * These use the names used for the property on DOM interfaces (the michael@0: * 'method' field in nsCSSPropList.h). michael@0: * michael@0: * Like ValueFor(), the caller must check that the property is within michael@0: * mSIDs. michael@0: */ michael@0: #define CSS_PROP_PUBLIC_OR_PRIVATE(publicname_, privatename_) privatename_ michael@0: #define CSS_PROP(name_, id_, method_, flags_, pref_, parsevariant_, \ michael@0: kwtable_, stylestruct_, stylestructoffset_, animtype_) \ michael@0: nsCSSValue* ValueFor##method_() { \ michael@0: NS_ABORT_IF_FALSE(mSIDs & NS_STYLE_INHERIT_BIT(stylestruct_), \ michael@0: "Calling nsRuleData::ValueFor" #method_ " without " \ michael@0: "NS_STYLE_INHERIT_BIT(" #stylestruct_ " in mSIDs."); \ michael@0: nsStyleStructID sid = eStyleStruct_##stylestruct_; \ michael@0: size_t indexInStruct = \ michael@0: nsCSSProps::PropertyIndexInStruct(eCSSProperty_##id_); \ michael@0: NS_ABORT_IF_FALSE(sid != eStyleStruct_BackendOnly && \ michael@0: indexInStruct != size_t(-1), \ michael@0: "backend-only property"); \ michael@0: return mValueStorage + mValueOffsets[sid] + indexInStruct; \ michael@0: } \ michael@0: const nsCSSValue* ValueFor##method_() const { \ michael@0: return const_cast(this)->ValueFor##method_(); \ michael@0: } michael@0: #define CSS_PROP_BACKENDONLY(name_, id_, method_, flags_, pref_, \ michael@0: parsevariant_, kwtable_) \ michael@0: /* empty; backend-only structs are not in nsRuleData */ michael@0: #include "nsCSSPropList.h" michael@0: #undef CSS_PROP michael@0: #undef CSS_PROP_PUBLIC_OR_PRIVATE michael@0: #undef CSS_PROP_BACKENDONLY michael@0: michael@0: private: michael@0: inline size_t GetPoisonOffset(); michael@0: michael@0: }; michael@0: michael@0: #endif