diff options
author | Russell Brenner <russellbrenner@google.com> | 2010-11-18 17:33:13 -0800 |
---|---|---|
committer | Russell Brenner <russellbrenner@google.com> | 2010-12-02 13:47:21 -0800 |
commit | 6b70adc33054f8aee8c54d0f460458a9df11b8a5 (patch) | |
tree | 103a13998c33944d6ab3b8318c509a037e639460 /WebCore/css/CSSPrimitiveValue.cpp | |
parent | bdf4ebc8e70b2d221b6ee7a65660918ecb1d33aa (diff) | |
download | external_webkit-6b70adc33054f8aee8c54d0f460458a9df11b8a5.zip external_webkit-6b70adc33054f8aee8c54d0f460458a9df11b8a5.tar.gz external_webkit-6b70adc33054f8aee8c54d0f460458a9df11b8a5.tar.bz2 |
Merge WebKit at r72274: Initial merge by git.
Change-Id: Ie51f0b4a16da82942bd516dce59cfb79ebbe25fb
Diffstat (limited to 'WebCore/css/CSSPrimitiveValue.cpp')
-rw-r--r-- | WebCore/css/CSSPrimitiveValue.cpp | 201 |
1 files changed, 135 insertions, 66 deletions
diff --git a/WebCore/css/CSSPrimitiveValue.cpp b/WebCore/css/CSSPrimitiveValue.cpp index 065c244..ce1b87b 100644 --- a/WebCore/css/CSSPrimitiveValue.cpp +++ b/WebCore/css/CSSPrimitiveValue.cpp @@ -36,6 +36,7 @@ #include "RenderStyle.h" #include <wtf/ASCIICType.h> #include <wtf/DecimalNumber.h> +#include <wtf/MathExtras.h> #include <wtf/StdLibExtras.h> #include <wtf/text/StringBuffer.h> @@ -47,6 +48,38 @@ using namespace WTF; namespace WebCore { +static CSSPrimitiveValue::UnitCategory unitCategory(CSSPrimitiveValue::UnitTypes type) +{ + // Here we violate the spec (http://www.w3.org/TR/DOM-Level-2-Style/css.html#CSS-CSSPrimitiveValue) and allow conversions + // between CSS_PX and relative lengths (see cssPixelsPerInch comment in CSSHelper.h for the topic treatment). + switch (type) { + case CSSPrimitiveValue::CSS_NUMBER: + return CSSPrimitiveValue::UNumber; + case CSSPrimitiveValue::CSS_PERCENTAGE: + return CSSPrimitiveValue::UPercent; + case CSSPrimitiveValue::CSS_PX: + case CSSPrimitiveValue::CSS_CM: + case CSSPrimitiveValue::CSS_MM: + case CSSPrimitiveValue::CSS_IN: + case CSSPrimitiveValue::CSS_PT: + case CSSPrimitiveValue::CSS_PC: + return CSSPrimitiveValue::ULength; + case CSSPrimitiveValue::CSS_MS: + case CSSPrimitiveValue::CSS_S: + return CSSPrimitiveValue::UTime; + case CSSPrimitiveValue::CSS_DEG: + case CSSPrimitiveValue::CSS_RAD: + case CSSPrimitiveValue::CSS_GRAD: + case CSSPrimitiveValue::CSS_TURN: + return CSSPrimitiveValue::UAngle; + case CSSPrimitiveValue::CSS_HZ: + case CSSPrimitiveValue::CSS_KHZ: + return CSSPrimitiveValue::UFrequency; + default: + return CSSPrimitiveValue::UOther; + } +} + typedef HashMap<const CSSPrimitiveValue*, String> CSSTextCache; static CSSTextCache& cssTextCache() { @@ -55,7 +88,7 @@ static CSSTextCache& cssTextCache() } // A more stylish solution than sharing would be to turn CSSPrimitiveValue (or CSSValues in general) into non-virtual, -// non-refcounted simple type with value semantics. In practice these sharing tricks get similar memory benefits +// non-refcounted simple type with value semantics. In practice these sharing tricks get similar memory benefits // with less need for refactoring. inline PassRefPtr<CSSPrimitiveValue> CSSPrimitiveValue::createUncachedIdentifier(int identifier) @@ -274,7 +307,6 @@ void CSSPrimitiveValue::cleanup() case CSS_STRING: case CSS_URI: case CSS_ATTR: - case CSS_PARSER_VARIABLE_FUNCTION_SYNTAX: case CSS_PARSER_HEXCOLOR: if (m_value.string) m_value.string->deref(); @@ -408,26 +440,24 @@ double CSSPrimitiveValue::computeLengthDouble(RenderStyle* style, RenderStyle* r return zoomedResult; } -void CSSPrimitiveValue::setFloatValue(unsigned short unitType, double floatValue, ExceptionCode& ec) +void CSSPrimitiveValue::setFloatValue(unsigned short, double, ExceptionCode& ec) { - ec = 0; - - if (m_type < CSS_NUMBER || m_type > CSS_DIMENSION || unitType < CSS_NUMBER || unitType > CSS_DIMENSION) { - ec = INVALID_ACCESS_ERR; - return; - } - - cleanup(); - - m_value.num = floatValue; - m_type = unitType; + // Keeping values immutable makes optimizations easier and allows sharing of the primitive value objects. + // No other engine supports mutating style through this API. Computed style is always read-only anyway. + // Supporting setter would require making primitive value copy-on-write and taking care of style invalidation. + ec = NO_MODIFICATION_ALLOWED_ERR; } -static double scaleFactorForConversion(unsigned short unitType) +static double conversionToCanonicalUnitsScaleFactor(unsigned short unitType) { double factor = 1.0; + // FIXME: the switch can be replaced by an array of scale factors. switch (unitType) { + // These are "canonical" units in their respective categories. case CSSPrimitiveValue::CSS_PX: + case CSSPrimitiveValue::CSS_DEG: + case CSSPrimitiveValue::CSS_MS: + case CSSPrimitiveValue::CSS_HZ: break; case CSSPrimitiveValue::CSS_CM: factor = cssPixelsPerInch / 2.54; // (2.54 cm/in) @@ -444,6 +474,19 @@ static double scaleFactorForConversion(unsigned short unitType) case CSSPrimitiveValue::CSS_PC: factor = cssPixelsPerInch * 12.0 / 72.0; // 1 pc == 12 pt break; + case CSSPrimitiveValue::CSS_RAD: + factor = 180 / piDouble; + break; + case CSSPrimitiveValue::CSS_GRAD: + factor = 0.9; + break; + case CSSPrimitiveValue::CSS_TURN: + factor = 360; + break; + case CSSPrimitiveValue::CSS_S: + case CSSPrimitiveValue::CSS_KHZ: + factor = 1000; + break; default: break; } @@ -451,69 +494,103 @@ static double scaleFactorForConversion(unsigned short unitType) return factor; } -double CSSPrimitiveValue::getDoubleValue(unsigned short unitType, ExceptionCode& ec) +double CSSPrimitiveValue::getDoubleValue(unsigned short unitType, ExceptionCode& ec) const { - ec = 0; - if (m_type < CSS_NUMBER || m_type > CSS_DIMENSION || unitType < CSS_NUMBER || unitType > CSS_DIMENSION) { + double result = 0; + bool success = getDoubleValueInternal(static_cast<UnitTypes>(unitType), &result); + if (!success) { ec = INVALID_ACCESS_ERR; return 0.0; } - if (unitType == m_type || unitType < CSS_PX || unitType > CSS_PC) - return m_value.num; + ec = 0; + return result; +} + +double CSSPrimitiveValue::getDoubleValue(unsigned short unitType) const +{ + double result = 0; + getDoubleValueInternal(static_cast<UnitTypes>(unitType), &result); + return result; +} + +CSSPrimitiveValue::UnitTypes CSSPrimitiveValue::canonicalUnitTypeForCategory(UnitCategory category) +{ + // The canonical unit type is chosen according to the way CSSParser::validUnit() chooses the default unit + // in each category (based on unitflags). + switch (category) { + case UNumber: + return CSS_NUMBER; + case ULength: + return CSS_PX; + case UPercent: + return CSS_UNKNOWN; // Cannot convert between numbers and percent. + case UTime: + return CSS_MS; + case UAngle: + return CSS_DEG; + case UFrequency: + return CSS_HZ; + default: + return CSS_UNKNOWN; + } +} - double convertedValue = m_value.num; +bool CSSPrimitiveValue::getDoubleValueInternal(UnitTypes requestedUnitType, double* result) const +{ + if (m_type < CSS_NUMBER || (m_type > CSS_DIMENSION && m_type < CSS_TURN) || requestedUnitType < CSS_NUMBER || (requestedUnitType > CSS_DIMENSION && requestedUnitType < CSS_TURN)) + return false; + if (requestedUnitType == m_type || requestedUnitType == CSS_DIMENSION) { + *result = m_value.num; + return true; + } - // First convert the value from m_type into CSSPixels - double factor = scaleFactorForConversion(m_type); - convertedValue *= factor; + UnitTypes sourceUnitType = static_cast<UnitTypes>(m_type); + UnitCategory sourceCategory = unitCategory(sourceUnitType); + ASSERT(sourceCategory != UOther); - // Now convert from CSSPixels to the specified unitType - factor = scaleFactorForConversion(unitType); - convertedValue /= factor; + UnitTypes targetUnitType = requestedUnitType; + UnitCategory targetCategory = unitCategory(targetUnitType); + ASSERT(targetCategory != UOther); - return convertedValue; -} + // Cannot convert between unrelated unit categories if one of them is not UNumber. + if (sourceCategory != targetCategory && sourceCategory != UNumber && targetCategory != UNumber) + return false; -double CSSPrimitiveValue::getDoubleValue(unsigned short unitType) -{ - if (m_type < CSS_NUMBER || m_type > CSS_DIMENSION || unitType < CSS_NUMBER || unitType > CSS_DIMENSION) - return 0; + if (targetCategory == UNumber) { + // We interpret conversion to CSS_NUMBER as conversion to a canonical unit in this value's category. + targetUnitType = canonicalUnitTypeForCategory(sourceCategory); + if (targetUnitType == CSS_UNKNOWN) + return false; + } - if (unitType == m_type || unitType < CSS_PX || unitType > CSS_PC) - return m_value.num; + if (sourceUnitType == CSS_NUMBER) { + // We interpret conversion from CSS_NUMBER in the same way as CSSParser::validUnit() while using non-strict mode. + sourceUnitType = canonicalUnitTypeForCategory(targetCategory); + if (sourceUnitType == CSS_UNKNOWN) + return false; + } double convertedValue = m_value.num; - // First convert the value from m_type into CSSPixels - double factor = scaleFactorForConversion(m_type); + // First convert the value from m_type to canonical type. + double factor = conversionToCanonicalUnitsScaleFactor(sourceUnitType); convertedValue *= factor; - // Now convert from CSSPixels to the specified unitType - factor = scaleFactorForConversion(unitType); + // Now convert from canonical type to the target unitType. + factor = conversionToCanonicalUnitsScaleFactor(targetUnitType); convertedValue /= factor; - return convertedValue; + *result = convertedValue; + return true; } - -void CSSPrimitiveValue::setStringValue(unsigned short stringType, const String& stringValue, ExceptionCode& ec) +void CSSPrimitiveValue::setStringValue(unsigned short, const String&, ExceptionCode& ec) { - ec = 0; - - if (m_type < CSS_STRING || m_type > CSS_ATTR || stringType < CSS_STRING || stringType > CSS_ATTR) { - ec = INVALID_ACCESS_ERR; - return; - } - - cleanup(); - - if (stringType != CSS_IDENT) { - m_value.string = stringValue.impl(); - m_value.string->ref(); - m_type = stringType; - } - // FIXME: parse ident + // Keeping values immutable makes optimizations easier and allows sharing of the primitive value objects. + // No other engine supports mutating style through this API. Computed style is always read-only anyway. + // Supporting setter would require making primitive value copy-on-write and taking care of style invalidation. + ec = NO_MODIFICATION_ALLOWED_ERR; } String CSSPrimitiveValue::getStringValue(ExceptionCode& ec) const @@ -523,7 +600,6 @@ String CSSPrimitiveValue::getStringValue(ExceptionCode& ec) const case CSS_STRING: case CSS_ATTR: case CSS_URI: - case CSS_PARSER_VARIABLE_FUNCTION_SYNTAX: return m_value.string; case CSS_IDENT: return valueOrPropertyName(m_value.ident); @@ -541,7 +617,6 @@ String CSSPrimitiveValue::getStringValue() const case CSS_STRING: case CSS_ATTR: case CSS_URI: - case CSS_PARSER_VARIABLE_FUNCTION_SYNTAX: return m_value.string; case CSS_IDENT: return valueOrPropertyName(m_value.ident); @@ -608,7 +683,7 @@ bool CSSPrimitiveValue::parseString(const String& /*string*/, bool /*strict*/) return false; } -int CSSPrimitiveValue::getIdent() +int CSSPrimitiveValue::getIdent() const { if (m_type != CSS_IDENT) return 0; @@ -823,11 +898,6 @@ String CSSPrimitiveValue::cssText() const } break; #endif - case CSS_PARSER_VARIABLE_FUNCTION_SYNTAX: - text = "-webkit-var("; - text += m_value.string; - text += ")"; - break; case CSS_PARSER_OPERATOR: { char c = static_cast<char>(m_value.ident); text = String(&c, 1U); @@ -877,7 +947,6 @@ CSSParserValue CSSPrimitiveValue::parserValue() const break; case CSS_STRING: case CSS_URI: - case CSS_PARSER_VARIABLE_FUNCTION_SYNTAX: case CSS_PARSER_HEXCOLOR: value.string.characters = const_cast<UChar*>(m_value.string->characters()); value.string.length = m_value.string->length(); |