/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* * an object that stores the result of determining whether a style struct that * was computed can be cached in the rule tree, and if so, what the conditions * it relies on are */ #ifndef RuleNodeCacheConditions_h_ #define RuleNodeCacheConditions_h_ #include "mozilla/Attributes.h" #include "nsCoord.h" #include "nsTArray.h" class nsStyleContext; namespace mozilla { /** * nsRuleNodeCacheConditions is used to store information about whether * we can store a style struct that we're computing in the rule tree. * * For inherited structs (i.e., structs with inherited properties), we * cache the struct in the rule tree if it does not depend on any data * in the style context tree, and otherwise store it in the style * context tree. This means that for inherited structs, setting any * conditions is equivalent to making the struct uncacheable. * * For reset structs (i.e., structs with non-inherited properties), we * are also able to cache structs in the rule tree conditionally on * certain common conditions. For these structs, setting conditions * (SetFontSizeDependency, SetWritingModeDependency) instead causes the * struct to be stored, with the condition, in the rule tree. */ class RuleNodeCacheConditions { public: RuleNodeCacheConditions() : mFontSize(0), mBits(0) {} RuleNodeCacheConditions(const RuleNodeCacheConditions& aOther) : mFontSize(aOther.mFontSize), mBits(aOther.mBits) {} RuleNodeCacheConditions& operator=(const RuleNodeCacheConditions& aOther) { mFontSize = aOther.mFontSize; mBits = aOther.mBits; return *this; } bool operator==(const RuleNodeCacheConditions& aOther) const { return mFontSize == aOther.mFontSize && mBits == aOther.mBits; } bool operator!=(const RuleNodeCacheConditions& aOther) const { return !(*this == aOther); } bool Matches(nsStyleContext* aStyleContext) const; /** * Record that the data being computed depend on the font-size * property of the element for which they are being computed. * * Note that we sometimes actually call this when there is a * dependency on the font-size property of the parent element, but we * only do so while computing inherited structs (nsStyleFont), and we * only store reset structs conditionally. */ void SetFontSizeDependency(nscoord aCoord) { MOZ_ASSERT(!(mBits & eHaveFontSize) || mFontSize == aCoord); mFontSize = aCoord; mBits |= eHaveFontSize; } /** * Record that the data being computed depend on the writing mode of * the element for which they are being computed, which in turn * depends on its 'writing-mode', 'direction', and 'text-orientation' * properties. */ void SetWritingModeDependency(uint8_t aWritingMode) { MOZ_ASSERT(!(mBits & eHaveWritingMode) || GetWritingMode() == aWritingMode); mBits |= (static_cast(aWritingMode) << eWritingModeShift) | eHaveWritingMode; } void SetUncacheable() { mBits |= eUncacheable; } void Clear() { *this = RuleNodeCacheConditions(); } bool Cacheable() const { return !(mBits & eUncacheable); } bool CacheableWithDependencies() const { return !(mBits & eUncacheable) && (mBits & eHaveBitsMask) != 0; } bool CacheableWithoutDependencies() const { // We're not uncacheable and we have don't have a font-size or // writing mode value. return (mBits & eHaveBitsMask) == 0; } #ifdef DEBUG void List() const; #endif private: enum { eUncacheable = 0x0001, eHaveFontSize = 0x0002, eHaveWritingMode = 0x0004, eHaveBitsMask = 0x00ff, eWritingModeMask = 0xff00, eWritingModeShift = 8, }; uint8_t GetWritingMode() const { return static_cast( (mBits & eWritingModeMask) >> eWritingModeShift); } // The font size from which em units are derived. nscoord mFontSize; // Values in mBits: // bit 0: are we set to "uncacheable"? // bit 1: do we have a font size value? // bit 2: do we have a writing mode value? // bits 3-7: unused // bits 8-15: writing mode (uint8_t) // bits 16-31: unused uint32_t mBits; }; } // namespace mozilla #endif // !defined(RuleNodeCacheConditions_h_)