Index: Source/core/css/CSSPrimitiveValue.h |
diff --git a/Source/core/css/CSSPrimitiveValue.h b/Source/core/css/CSSPrimitiveValue.h |
index 272fc24f553af70d11fa0477d950915a2a884abe..a810b39136c13da67a088033ce8e128cc5ad6347 100644 |
--- a/Source/core/css/CSSPrimitiveValue.h |
+++ b/Source/core/css/CSSPrimitiveValue.h |
@@ -25,7 +25,7 @@ |
#include "core/CSSPropertyNames.h" |
#include "core/CSSValueKeywords.h" |
#include "core/CoreExport.h" |
-#include "core/css/CSSValue.h" |
+#include "core/css/CSSValueObject.h" |
#include "platform/graphics/Color.h" |
#include "wtf/BitVector.h" |
#include "wtf/Forward.h" |
@@ -67,11 +67,29 @@ template<> inline float roundForImpreciseConversion(double value) |
return static_cast<float>(value); |
} |
-// CSSPrimitiveValues are immutable. This class has manual ref-counting |
-// of unioned types and does not have the code necessary |
-// to handle any kind of mutations. |
-class CORE_EXPORT CSSPrimitiveValue : public CSSValueObject { |
+// A type of unpacked CSSValue for CSSPrimitiveValue objects. Can only be stack-allocated; |
+// pass these around by value. |
+// Currently only supports CSSLargePrimitiveValues, but will later support tagged pointers |
+// stored as immediates in CSSValues. |
+// TODO(sashab): Add tagged pointer support. |
+class CORE_EXPORT CSSPrimitiveValue { |
+ STACK_ALLOCATED(); |
public: |
+ typedef union { |
+ CSSPropertyID propertyID; |
+ CSSValueID valueID; |
+ double num; |
+ StringImpl* string; |
+ RGBA32 rgbcolor; |
+ // FIXME: oilpan: Should be members, but no support for members in unions. Just trace the raw ptr for now. |
+ CSSBasicShape* shape; |
+ CSSCalcValue* calc; |
+ Counter* counter; |
+ Pair* pair; |
+ Rect* rect; |
+ Quad* quad; |
+ } CSSPrimitiveValueData; |
+ |
enum UnitType { |
CSS_UNKNOWN = 0, |
CSS_NUMBER = 1, |
@@ -141,6 +159,90 @@ public: |
typedef Vector<double, CSSPrimitiveValue::LengthUnitTypeCount> CSSLengthArray; |
typedef BitVector CSSLengthTypeArray; |
+ // No methods here, don't use this. It's just for large value storage. |
+ // IMPORTANT: You should never actually make one of these outside the parser. |
+ class CSSLargePrimitiveValue final : public CSSValueObject { |
+ friend class CSSPrimitiveValue; |
+ public: |
+ CSSLargePrimitiveValue(CSSValueID); |
+ CSSLargePrimitiveValue(CSSPropertyID); |
+ CSSLargePrimitiveValue(RGBA32 color); |
+ CSSLargePrimitiveValue(const Length&, float zoom); |
+ CSSLargePrimitiveValue(const LengthSize&, const ComputedStyle&); |
+ CSSLargePrimitiveValue(const String&, UnitType); |
+ CSSLargePrimitiveValue(double, UnitType); |
+ CSSLargePrimitiveValue(double, UnitType, bool isQuirkValue); |
+ |
+ template<typename T> CSSLargePrimitiveValue(T); // Defined in CSSPrimitiveValueMappings.h |
+ template<typename T> CSSLargePrimitiveValue(T* val) |
+ : CSSValueObject(PrimitiveClass) |
+ { |
+ init(PassRefPtrWillBeRawPtr<T>(val)); |
+ } |
+ |
+ template<typename T> CSSLargePrimitiveValue(PassRefPtrWillBeRawPtr<T> val) |
+ : CSSValueObject(PrimitiveClass) |
+ { |
+ init(val); |
+ } |
+ |
+ |
+ ~CSSLargePrimitiveValue(); |
+ |
+ void cleanup(); |
+ |
+ DECLARE_TRACE_AFTER_DISPATCH(); |
+ |
+ private: |
+ void init(const Length&); |
+ void init(const LengthSize&, const ComputedStyle&); |
+ void init(PassRefPtrWillBeRawPtr<Counter>); |
+ void init(PassRefPtrWillBeRawPtr<Rect>); |
+ void init(PassRefPtrWillBeRawPtr<Pair>); |
+ void init(PassRefPtrWillBeRawPtr<Quad>); |
+ void init(PassRefPtrWillBeRawPtr<CSSBasicShape>); |
+ void init(PassRefPtrWillBeRawPtr<CSSCalcValue>); |
+ |
+ CSSPrimitiveValueData m_value; |
+ }; |
+ |
+ explicit CSSPrimitiveValue(const CSSLargePrimitiveValue* object) |
+ : m_rawValue(const_cast<CSSLargePrimitiveValue*>(object)) |
+ { |
+ ref(); |
+ } |
+ |
+ CSSPrimitiveValue(PassRefPtrWillBeRawPtr<CSSLargePrimitiveValue> cssValue) |
+ : m_rawValue(cssValue.leakRef()) |
+ { |
+ } |
+ |
+ |
+ CSSPrimitiveValue(const CSSPrimitiveValue& other) |
+ : m_rawValue(other.m_rawValue) |
+ { |
+ ref(); |
+ } |
+ |
+ CSSPrimitiveValue& operator=(const CSSPrimitiveValue& rhs) |
+ { |
+ rhs.ref(); |
+ deref(); |
+ m_rawValue = rhs.m_rawValue; |
+ return *this; |
+ } |
+ |
+ ~CSSPrimitiveValue() |
+ { |
+ deref(); |
+ } |
+ |
+ |
+ CSSLargePrimitiveValue* get() const |
+ { |
+ return m_rawValue; |
+ } |
+ |
void accumulateLengthArray(CSSLengthArray&, double multiplier = 1) const; |
void accumulateLengthArray(CSSLengthArray&, CSSLengthTypeArray&, double multiplier = 1) const; |
@@ -163,22 +265,22 @@ public: |
bool isAngle() const |
{ |
- return m_primitiveUnitType == CSS_DEG |
- || m_primitiveUnitType == CSS_RAD |
- || m_primitiveUnitType == CSS_GRAD |
- || m_primitiveUnitType == CSS_TURN; |
+ return type() == CSS_DEG |
+ || type() == CSS_RAD |
+ || type() == CSS_GRAD |
+ || type() == CSS_TURN; |
} |
- bool isAttr() const { return m_primitiveUnitType == CSS_ATTR; } |
- bool isCounter() const { return m_primitiveUnitType == CSS_COUNTER; } |
- bool isCustomIdent() const { return m_primitiveUnitType == CSS_CUSTOM_IDENT; } |
+ bool isAttr() const { return type() == CSS_ATTR; } |
+ bool isCounter() const { return type() == CSS_COUNTER; } |
+ bool isCustomIdent() const { return type() == CSS_CUSTOM_IDENT; } |
bool isFontRelativeLength() const |
{ |
- return m_primitiveUnitType == CSS_EMS |
- || m_primitiveUnitType == CSS_EXS |
- || m_primitiveUnitType == CSS_REMS |
- || m_primitiveUnitType == CSS_CHS; |
+ return type() == CSS_EMS |
+ || type() == CSS_EXS |
+ || type() == CSS_REMS |
+ || type() == CSS_CHS; |
} |
- bool isViewportPercentageLength() const { return isViewportPercentageLength(static_cast<UnitType>(m_primitiveUnitType)); } |
+ bool isViewportPercentageLength() const { return isViewportPercentageLength(type()); } |
static bool isViewportPercentageLength(UnitType type) { return type >= CSS_VW && type <= CSS_VMAX; } |
static bool isLength(UnitType type) |
{ |
@@ -188,13 +290,13 @@ public: |
bool isNumber() const { return primitiveType() == CSS_NUMBER || primitiveType() == CSS_INTEGER; } |
bool isPercentage() const { return primitiveType() == CSS_PERCENTAGE; } |
bool isPx() const { return primitiveType() == CSS_PX; } |
- bool isRect() const { return m_primitiveUnitType == CSS_RECT; } |
- bool isRGBColor() const { return m_primitiveUnitType == CSS_RGBCOLOR; } |
- bool isShape() const { return m_primitiveUnitType == CSS_SHAPE; } |
- bool isString() const { return m_primitiveUnitType == CSS_STRING; } |
- bool isTime() const { return m_primitiveUnitType == CSS_S || m_primitiveUnitType == CSS_MS; } |
- bool isURI() const { return m_primitiveUnitType == CSS_URI; } |
- bool isCalculated() const { return m_primitiveUnitType == CSS_CALC; } |
+ bool isRect() const { return type() == CSS_RECT; } |
+ bool isRGBColor() const { return type() == CSS_RGBCOLOR; } |
+ bool isShape() const { return type() == CSS_SHAPE; } |
+ bool isString() const { return type() == CSS_STRING; } |
+ bool isTime() const { return type() == CSS_S || type() == CSS_MS; } |
+ bool isURI() const { return type() == CSS_URI; } |
+ bool isCalculated() const { return type() == CSS_CALC; } |
bool isCalculatedPercentageWithNumber() const { return primitiveType() == CSS_CALC_PERCENTAGE_WITH_NUMBER; } |
bool isCalculatedPercentageWithLength() const { return primitiveType() == CSS_CALC_PERCENTAGE_WITH_LENGTH; } |
static bool isDotsPerInch(UnitType type) { return type == CSS_DPI; } |
@@ -202,57 +304,51 @@ public: |
static bool isDotsPerCentimeter(UnitType type) { return type == CSS_DPCM; } |
static bool isResolution(UnitType type) { return type >= CSS_DPPX && type <= CSS_DPCM; } |
bool isFlex() const { return primitiveType() == CSS_FR; } |
- bool isValueID() const { return m_primitiveUnitType == CSS_VALUE_ID; } |
+ bool isValueID() const { return type() == CSS_VALUE_ID; } |
bool colorIsDerivedFromElement() const; |
- static PassRefPtrWillBeRawPtr<CSSPrimitiveValue> createIdentifier(CSSValueID valueID) |
+ static CSSPrimitiveValue createIdentifier(CSSValueID valueID) |
{ |
- return adoptRefWillBeNoop(new CSSPrimitiveValue(valueID)); |
+ return CSSPrimitiveValue(adoptRefWillBeNoop(new CSSLargePrimitiveValue(valueID))); |
} |
- static PassRefPtrWillBeRawPtr<CSSPrimitiveValue> createIdentifier(CSSPropertyID propertyID) |
+ static CSSPrimitiveValue createIdentifier(CSSPropertyID propertyID) |
{ |
- return adoptRefWillBeNoop(new CSSPrimitiveValue(propertyID)); |
+ return CSSPrimitiveValue(adoptRefWillBeNoop(new CSSLargePrimitiveValue(propertyID))); |
} |
- static PassRefPtrWillBeRawPtr<CSSPrimitiveValue> createColor(RGBA32 rgbValue) |
+ static CSSPrimitiveValue createColor(RGBA32 rgbValue) |
{ |
- return adoptRefWillBeNoop(new CSSPrimitiveValue(rgbValue)); |
+ return CSSPrimitiveValue(adoptRefWillBeNoop(new CSSLargePrimitiveValue(rgbValue))); |
} |
- static PassRefPtrWillBeRawPtr<CSSPrimitiveValue> create(double value, UnitType type) |
+ static CSSPrimitiveValue create(double value, UnitType type) |
{ |
- return adoptRefWillBeNoop(new CSSPrimitiveValue(value, type)); |
+ return CSSPrimitiveValue(adoptRefWillBeNoop(new CSSLargePrimitiveValue(value, type))); |
} |
- static PassRefPtrWillBeRawPtr<CSSPrimitiveValue> create(const String& value, UnitType type) |
+ static CSSPrimitiveValue create(const String& value, UnitType type) |
{ |
- return adoptRefWillBeNoop(new CSSPrimitiveValue(value, type)); |
+ return CSSPrimitiveValue(adoptRefWillBeNoop(new CSSLargePrimitiveValue(value, type))); |
} |
- static PassRefPtrWillBeRawPtr<CSSPrimitiveValue> create(const Length& value, float zoom) |
+ static CSSPrimitiveValue create(const Length& value, float zoom) |
{ |
- return adoptRefWillBeNoop(new CSSPrimitiveValue(value, zoom)); |
+ return CSSPrimitiveValue(adoptRefWillBeNoop(new CSSLargePrimitiveValue(value, zoom))); |
} |
- static PassRefPtrWillBeRawPtr<CSSPrimitiveValue> create(const LengthSize& value, const ComputedStyle& style) |
+ static CSSPrimitiveValue create(const LengthSize& value, const ComputedStyle& style) |
{ |
- return adoptRefWillBeNoop(new CSSPrimitiveValue(value, style)); |
+ return CSSPrimitiveValue(adoptRefWillBeNoop(new CSSLargePrimitiveValue(value, style))); |
} |
- template<typename T> static PassRefPtrWillBeRawPtr<CSSPrimitiveValue> create(T value) |
+ template<typename T> static CSSPrimitiveValue create(T value) |
{ |
- return adoptRefWillBeNoop(new CSSPrimitiveValue(value)); |
+ return CSSPrimitiveValue(adoptRefWillBeNoop(new CSSLargePrimitiveValue(value))); |
} |
// This value is used to handle quirky margins in reflow roots (body, td, and th) like WinIE. |
// The basic idea is that a stylesheet can use the value __qem (for quirky em) instead of em. |
// When the quirky value is used, if you're in quirks mode, the margin will collapse away |
// inside a table cell. |
- static PassRefPtrWillBeRawPtr<CSSPrimitiveValue> createAllowingMarginQuirk(double value, UnitType type) |
+ static CSSPrimitiveValue createAllowingMarginQuirk(double value, UnitType type) |
{ |
- CSSPrimitiveValue* quirkValue = new CSSPrimitiveValue(value, type); |
- quirkValue->m_isQuirkValue = true; |
- return adoptRefWillBeNoop(quirkValue); |
+ return CSSPrimitiveValue(adoptRefWillBeNoop(new CSSLargePrimitiveValue(value, type, true))); |
} |
- ~CSSPrimitiveValue(); |
- |
- void cleanup(); |
- |
UnitType primitiveType() const; |
double computeDegrees() const; |
@@ -271,33 +367,33 @@ public: |
String getStringValue() const; |
- Counter* getCounterValue() const { return m_primitiveUnitType != CSS_COUNTER ? 0 : m_value.counter; } |
+ Counter* getCounterValue() const { return type() != CSS_COUNTER ? 0 : value().counter; } |
- Rect* getRectValue() const { return m_primitiveUnitType != CSS_RECT ? 0 : m_value.rect; } |
+ Rect* getRectValue() const { return type() != CSS_RECT ? 0 : value().rect; } |
- Quad* getQuadValue() const { return m_primitiveUnitType != CSS_QUAD ? 0 : m_value.quad; } |
+ Quad* getQuadValue() const { return type() != CSS_QUAD ? 0 : value().quad; } |
- RGBA32 getRGBA32Value() const { return m_primitiveUnitType != CSS_RGBCOLOR ? 0 : m_value.rgbcolor; } |
+ RGBA32 getRGBA32Value() const { return type() != CSS_RGBCOLOR ? 0 : value().rgbcolor; } |
- Pair* getPairValue() const { return m_primitiveUnitType != CSS_PAIR ? 0 : m_value.pair; } |
+ Pair* getPairValue() const { return type() != CSS_PAIR ? 0 : value().pair; } |
- CSSBasicShape* getShapeValue() const { return m_primitiveUnitType != CSS_SHAPE ? 0 : m_value.shape; } |
+ CSSBasicShape* getShapeValue() const { return type() != CSS_SHAPE ? 0 : value().shape; } |
- CSSCalcValue* cssCalcValue() const { return m_primitiveUnitType != CSS_CALC ? 0 : m_value.calc; } |
+ CSSCalcValue* cssCalcValue() const { return type() != CSS_CALC ? 0 : value().calc; } |
- CSSPropertyID getPropertyID() const { return m_primitiveUnitType == CSS_PROPERTY_ID ? m_value.propertyID : CSSPropertyInvalid; } |
- CSSValueID getValueID() const { return m_primitiveUnitType == CSS_VALUE_ID ? m_value.valueID : CSSValueInvalid; } |
+ CSSPropertyID getPropertyID() const { return type() == CSS_PROPERTY_ID ? value().propertyID : CSSPropertyInvalid; } |
+ CSSValueID getValueID() const { return type() == CSS_VALUE_ID ? value().valueID : CSSValueInvalid; } |
template<typename T> inline operator T() const; // Defined in CSSPrimitiveValueMappings.h |
static const char* unitTypeToString(UnitType); |
+ // TODO(sashab): Remove customCSSText() once CSSValueObject uses vtables properly. |
String customCSSText() const; |
+ String cssText() const { return customCSSText(); } |
- bool isQuirkValue() { return m_isQuirkValue; } |
- |
- bool equals(const CSSPrimitiveValue&) const; |
+ bool isQuirkValue() const { return m_rawValue->m_isQuirkValue; } |
- DECLARE_TRACE_AFTER_DISPATCH(); |
+ bool equals(const CSSPrimitiveValue) const; |
static UnitType canonicalUnitTypeForCategory(UnitCategory); |
static double conversionToCanonicalUnitsScaleFactor(UnitType); |
@@ -306,64 +402,49 @@ public: |
static bool unitTypeToLengthUnitType(UnitType, LengthUnitType&); |
static UnitType lengthUnitTypeToUnitType(LengthUnitType); |
+ DEFINE_INLINE_TRACE() |
+ { |
+ visitor->trace(m_rawValue); |
+ m_rawValue->traceAfterDispatch(visitor); |
+ } |
+ |
private: |
- CSSPrimitiveValue(CSSValueID); |
- CSSPrimitiveValue(CSSPropertyID); |
- CSSPrimitiveValue(RGBA32 color); |
- CSSPrimitiveValue(const Length&, float zoom); |
- CSSPrimitiveValue(const LengthSize&, const ComputedStyle&); |
- CSSPrimitiveValue(const String&, UnitType); |
- CSSPrimitiveValue(double, UnitType); |
- |
- template<typename T> CSSPrimitiveValue(T); // Defined in CSSPrimitiveValueMappings.h |
- template<typename T> CSSPrimitiveValue(T* val) |
- : CSSValueObject(PrimitiveClass) |
+ void ref() const |
{ |
- init(PassRefPtrWillBeRawPtr<T>(val)); |
+#if !ENABLE(OILPAN) |
+ m_rawValue->ref(); |
+#endif |
} |
- template<typename T> CSSPrimitiveValue(PassRefPtrWillBeRawPtr<T> val) |
- : CSSValueObject(PrimitiveClass) |
+ void deref() const |
{ |
- init(val); |
+#if !ENABLE(OILPAN) |
+ m_rawValue->deref(); |
+#endif |
} |
static void create(int); // compile-time guard |
static void create(unsigned); // compile-time guard |
template<typename T> operator T*(); // compile-time guard |
- void init(const Length&); |
- void init(const LengthSize&, const ComputedStyle&); |
- void init(PassRefPtrWillBeRawPtr<Counter>); |
- void init(PassRefPtrWillBeRawPtr<Rect>); |
- void init(PassRefPtrWillBeRawPtr<Pair>); |
- void init(PassRefPtrWillBeRawPtr<Quad>); |
- void init(PassRefPtrWillBeRawPtr<CSSBasicShape>); |
- void init(PassRefPtrWillBeRawPtr<CSSCalcValue>); |
- |
double computeLengthDouble(const CSSToLengthConversionData&); |
- union { |
- CSSPropertyID propertyID; |
- CSSValueID valueID; |
- double num; |
- StringImpl* string; |
- RGBA32 rgbcolor; |
- // FIXME: oilpan: Should be members, but no support for members in unions. Just trace the raw ptr for now. |
- CSSBasicShape* shape; |
- CSSCalcValue* calc; |
- Counter* counter; |
- Pair* pair; |
- Rect* rect; |
- Quad* quad; |
- } m_value; |
+ RawPtrWillBeMember<CSSLargePrimitiveValue> m_rawValue; |
+ |
+ // Getters/setters for inner class. |
+ CSSPrimitiveValueData value() const { return m_rawValue->m_value; } |
+ UnitType type() const { return static_cast<UnitType>(m_rawValue->m_primitiveUnitType); } |
+ bool hasCachedCSSText() const { return m_rawValue->m_hasCachedCSSText; } |
+ |
+ void setValue(CSSPrimitiveValueData value) { m_rawValue->m_value = value; } |
+ void setType(UnitType primitiveUnitType) { m_rawValue->m_primitiveUnitType = static_cast<unsigned>(primitiveUnitType); } |
+ void setHasCachedCSSText(bool hasCachedCSSText) const { m_rawValue->m_hasCachedCSSText = hasCachedCSSText; } |
+ void setIsQuirkValue(bool isQuirkValue) { m_rawValue->m_isQuirkValue = isQuirkValue; } |
}; |
typedef CSSPrimitiveValue::CSSLengthArray CSSLengthArray; |
typedef CSSPrimitiveValue::CSSLengthTypeArray CSSLengthTypeArray; |
-DEFINE_CSS_VALUE_TYPE_CASTS(CSSPrimitiveValue, isPrimitiveValue()); |
- |
} // namespace blink |
#endif // CSSPrimitiveValue_h |