Index: Source/core/css/CSSPrimitiveValue.h |
diff --git a/Source/core/css/CSSPrimitiveValue.h b/Source/core/css/CSSPrimitiveValue.h |
index 272fc24f553af70d11fa0477d950915a2a884abe..d8b5e613ed0083ce6855741478fb0a4acabc9bd7 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, |
@@ -91,35 +109,35 @@ public: |
CSS_S = 15, |
CSS_HZ = 16, |
CSS_KHZ = 17, |
- CSS_CUSTOM_IDENT = 19, |
- CSS_URI = 20, |
- CSS_IDENT = 21, |
- CSS_ATTR = 22, |
- CSS_COUNTER = 23, |
- CSS_RECT = 24, |
- CSS_RGBCOLOR = 25, |
- CSS_VW = 26, |
- CSS_VH = 27, |
- CSS_VMIN = 28, |
- CSS_VMAX = 29, |
- CSS_DPPX = 30, |
- CSS_DPI = 31, |
- CSS_DPCM = 32, |
- CSS_FR = 33, |
- CSS_INTEGER = 34, |
- CSS_PAIR = 100, |
- CSS_TURN = 107, |
- CSS_REMS = 108, |
- CSS_CHS = 109, |
- CSS_SHAPE = 111, |
- CSS_QUAD = 112, |
- CSS_CALC = 113, |
- CSS_CALC_PERCENTAGE_WITH_NUMBER = 114, |
- CSS_CALC_PERCENTAGE_WITH_LENGTH = 115, |
- CSS_STRING = 116, |
- CSS_PROPERTY_ID = 117, |
- CSS_VALUE_ID = 118, |
- CSS_QEM = 119 |
+ CSS_CUSTOM_IDENT = 18, |
+ CSS_URI = 19, |
+ CSS_IDENT = 20, |
+ CSS_ATTR = 21, |
+ CSS_COUNTER = 22, |
+ CSS_RECT = 23, |
+ CSS_RGBCOLOR = 24, |
+ CSS_VW = 25, |
+ CSS_VH = 26, |
+ CSS_VMIN = 27, |
+ CSS_VMAX = 28, |
+ CSS_DPPX = 29, |
+ CSS_DPI = 30, |
+ CSS_DPCM = 31, |
+ CSS_FR = 32, |
+ CSS_INTEGER = 33, |
+ CSS_PAIR = 34, |
+ CSS_TURN = 35, |
+ CSS_REMS = 36, |
+ CSS_CHS = 37, |
+ CSS_SHAPE = 38, |
+ CSS_QUAD = 39, |
+ CSS_CALC = 40, |
+ CSS_CALC_PERCENTAGE_WITH_NUMBER = 41, |
+ CSS_CALC_PERCENTAGE_WITH_LENGTH = 42, |
+ CSS_STRING = 43, |
+ CSS_PROPERTY_ID = 44, |
+ CSS_VALUE_ID = 45, |
+ CSS_QEM = 46 |
}; |
enum LengthUnitType { |
@@ -141,6 +159,103 @@ 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& operator=(CSSPrimitiveValue&& rhs) |
+ { |
+ m_rawValue = rhs.m_rawValue; |
+ rhs.m_rawValue.clear(); |
+ return *this; |
+ } |
+ |
+ CSSPrimitiveValue(CSSPrimitiveValue&& rhs) |
+ : m_rawValue(rhs.m_rawValue) |
+ { |
+ rhs.m_rawValue.clear(); |
+ } |
+ |
+ ~CSSPrimitiveValue() |
+ { |
+ deref(); |
+ } |
+ |
+ |
+ CSSLargePrimitiveValue* get() const |
+ { |
+ return m_rawValue.get(); |
+ } |
+ |
void accumulateLengthArray(CSSLengthArray&, double multiplier = 1) const; |
void accumulateLengthArray(CSSLengthArray&, CSSLengthTypeArray&, double multiplier = 1) const; |
@@ -163,22 +278,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 +303,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,67 +317,62 @@ 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; |
- double computeSeconds(); |
+ double computeSeconds() const; |
// Computes a length in pixels, resolving relative lengths |
- template<typename T> T computeLength(const CSSToLengthConversionData&); |
+ template<typename T> T computeLength(const CSSToLengthConversionData&) const; |
// Converts to a Length (Fixed, Percent or Calculated) |
- Length convertToLength(const CSSToLengthConversionData&); |
+ Length convertToLength(const CSSToLengthConversionData&) const; |
double getDoubleValue() const; |
float getFloatValue() const { return getValue<float>(); } |
@@ -271,33 +381,36 @@ 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,63 +419,54 @@ 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) |
+ // Might be null due to move semantics. |
+ if (m_rawValue) |
+ 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&) const; |
- double computeLengthDouble(const CSSToLengthConversionData&); |
+ RawPtrWillBeMember<CSSLargePrimitiveValue> m_rawValue; |
+ static_assert(sizeof(m_rawValue) == sizeof(void*), "The tagged pointer field in CSSPrimitiveValue must be the size of a pointer"); |
- 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; |
+ // Getters/setters for inner class. |
+ CSSPrimitiveValueData value() const |
+ { |
+ return m_rawValue->m_value; |
+ } |
+ |
+ UnitType type() const |
+ { |
+ return static_cast<UnitType>(m_rawValue->m_primitiveUnitType); |
+ } |
}; |
typedef CSSPrimitiveValue::CSSLengthArray CSSLengthArray; |
typedef CSSPrimitiveValue::CSSLengthTypeArray CSSLengthTypeArray; |
-DEFINE_CSS_VALUE_TYPE_CASTS(CSSPrimitiveValue, isPrimitiveValue()); |
+static_assert(sizeof(CSSPrimitiveValue) == sizeof(void*), "CSSPrimitiveValue must be the size of a pointer"); |
} // namespace blink |