Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1011)

Unified Diff: third_party/WebKit/Source/core/svg/SVGLength.cpp

Issue 1421533006: Make SVGLength wrap a CSSPrimitiveValue. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Added expectation Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/core/svg/SVGLength.cpp
diff --git a/third_party/WebKit/Source/core/svg/SVGLength.cpp b/third_party/WebKit/Source/core/svg/SVGLength.cpp
index decc141174f4362309d65185a707f37e147b7b38..075649fe8654ad8732510410bd30e21a07c1b5be 100644
--- a/third_party/WebKit/Source/core/svg/SVGLength.cpp
+++ b/third_party/WebKit/Source/core/svg/SVGLength.cpp
@@ -26,6 +26,9 @@
#include "bindings/core/v8/ExceptionState.h"
#include "core/SVGNames.h"
#include "core/css/CSSPrimitiveValue.h"
+#include "core/css/CSSValue.h"
+#include "core/css/CSSValuePool.h"
+#include "core/css/parser/CSSParser.h"
#include "core/dom/ExceptionCode.h"
#include "core/svg/SVGAnimationElement.h"
#include "core/svg/SVGParserUtilities.h"
@@ -35,115 +38,27 @@
namespace blink {
-namespace {
-
-inline const char* lengthTypeToString(SVGLengthType type)
-{
- switch (type) {
- case LengthTypeUnknown:
- case LengthTypeNumber:
- return "";
- case LengthTypePercentage:
- return "%";
- case LengthTypeEMS:
- return "em";
- case LengthTypeEXS:
- return "ex";
- case LengthTypePX:
- return "px";
- case LengthTypeCM:
- return "cm";
- case LengthTypeMM:
- return "mm";
- case LengthTypeIN:
- return "in";
- case LengthTypePT:
- return "pt";
- case LengthTypePC:
- return "pc";
- case LengthTypeREMS:
- return "rem";
- case LengthTypeCHS:
- return "ch";
- }
-
- ASSERT_NOT_REACHED();
- return "";
-}
-
-template<typename CharType>
-SVGLengthType stringToLengthType(const CharType*& ptr, const CharType* end)
-{
- if (ptr == end)
- return LengthTypeNumber;
-
- SVGLengthType type = LengthTypeUnknown;
- const CharType firstChar = *ptr++;
-
- if (firstChar == '%') {
- type = LengthTypePercentage;
- } else if (isHTMLSpace<CharType>(firstChar)) {
- type = LengthTypeNumber;
- } else if (ptr < end) {
- const CharType secondChar = *ptr++;
-
- if (firstChar == 'p') {
- if (secondChar == 'x')
- type = LengthTypePX;
- if (secondChar == 't')
- type = LengthTypePT;
- if (secondChar == 'c')
- type = LengthTypePC;
- } else if (firstChar == 'e') {
- if (secondChar == 'm')
- type = LengthTypeEMS;
- if (secondChar == 'x')
- type = LengthTypeEXS;
- } else if (firstChar == 'r') {
- if (secondChar == 'e' && ptr < end) {
- const CharType thirdChar = *ptr++;
- if (thirdChar == 'm')
- type = LengthTypeREMS;
- }
- } else if (firstChar == 'c') {
- if (secondChar == 'h')
- type = LengthTypeCHS;
- if (secondChar == 'm')
- type = LengthTypeCM;
- } else if (firstChar == 'm' && secondChar == 'm') {
- type = LengthTypeMM;
- } else if (firstChar == 'i' && secondChar == 'n') {
- type = LengthTypeIN;
- } else if (isHTMLSpace<CharType>(firstChar) && isHTMLSpace<CharType>(secondChar)) {
- type = LengthTypeNumber;
- }
- }
-
- if (!skipOptionalSVGSpaces(ptr, end))
- return type;
-
- return LengthTypeUnknown;
-}
-
-} // namespace
-
SVGLength::SVGLength(SVGLengthMode mode)
: SVGPropertyBase(classType())
- , m_valueInSpecifiedUnits(0)
+ , m_value(cssValuePool().createValue(0, CSSPrimitiveValue::UnitType::UserUnits))
, m_unitMode(static_cast<unsigned>(mode))
- , m_unitType(LengthTypeNumber)
{
ASSERT(unitMode() == mode);
}
SVGLength::SVGLength(const SVGLength& o)
: SVGPropertyBase(classType())
- , m_valueInSpecifiedUnits(o.m_valueInSpecifiedUnits)
+ , m_value(o.m_value)
, m_unitMode(o.m_unitMode)
- , m_unitType(o.m_unitType)
{
}
+DEFINE_TRACE(SVGLength)
+{
+ visitor->trace(m_value);
+ SVGPropertyBase::trace(visitor);
+}
+
PassRefPtrWillBeRawPtr<SVGLength> SVGLength::clone() const
{
return adoptRefWillBeNoop(new SVGLength(*this));
@@ -154,13 +69,11 @@ PassRefPtrWillBeRawPtr<SVGPropertyBase> SVGLength::cloneForAnimation(const Strin
RefPtrWillBeRawPtr<SVGLength> length = create();
length->m_unitMode = m_unitMode;
- length->m_unitType = m_unitType;
TrackExceptionState exceptionState;
length->setValueAsString(value, exceptionState);
if (exceptionState.hadException()) {
- length->m_unitType = LengthTypeNumber;
- length->m_valueInSpecifiedUnits = 0;
+ length->m_value = CSSPrimitiveValue::create(0, CSSPrimitiveValue::UnitType::UserUnits);
}
return length.release();
@@ -168,116 +81,108 @@ PassRefPtrWillBeRawPtr<SVGPropertyBase> SVGLength::cloneForAnimation(const Strin
bool SVGLength::operator==(const SVGLength& other) const
{
- return m_unitMode == other.m_unitMode
- && m_unitType == other.m_unitType
- && m_valueInSpecifiedUnits == other.m_valueInSpecifiedUnits;
+ return m_unitMode == other.m_unitMode && m_value == other.m_value;
}
float SVGLength::value(const SVGLengthContext& context) const
{
- return context.convertValueToUserUnits(m_valueInSpecifiedUnits, unitMode(), unitType());
+ return context.convertValueToUserUnits(
+ m_value->getFloatValue(), unitMode(), m_value->typeWithCalcResolved());
}
void SVGLength::setValue(float value, const SVGLengthContext& context)
{
- m_valueInSpecifiedUnits = context.convertValueFromUserUnits(value, unitMode(), unitType());
+ m_value = CSSPrimitiveValue::create(
+ context.convertValueFromUserUnits(value, unitMode(), m_value->typeWithCalcResolved()),
+ m_value->typeWithCalcResolved());
+}
+
+bool isSupportedCSSUnitType(CSSPrimitiveValue::UnitType type)
+{
+ return type != CSSPrimitiveValue::UnitType::Unknown
+ && (type <= CSSPrimitiveValue::UnitType::UserUnits
+ || type == CSSPrimitiveValue::UnitType::Chs
+ || type == CSSPrimitiveValue::UnitType::Rems);
}
-void SVGLength::setUnitType(SVGLengthType type)
+void SVGLength::setUnitType(CSSPrimitiveValue::UnitType type)
{
- ASSERT(type != LengthTypeUnknown && type <= LengthTypeCHS);
- m_unitType = type;
+ ASSERT(isSupportedCSSUnitType(type));
+ m_value = CSSPrimitiveValue::create(m_value->getFloatValue(), type);
}
float SVGLength::valueAsPercentage() const
{
// LengthTypePercentage is represented with 100% = 100.0. Good for accuracy but could eventually be changed.
- if (m_unitType == LengthTypePercentage) {
+ if (m_value->isPercentage()) {
// Note: This division is a source of floating point inaccuracy.
- return m_valueInSpecifiedUnits / 100;
+ return m_value->getFloatValue() / 100;
}
- return m_valueInSpecifiedUnits;
+ return m_value->getFloatValue();
}
float SVGLength::valueAsPercentage100() const
{
// LengthTypePercentage is represented with 100% = 100.0. Good for accuracy but could eventually be changed.
- if (m_unitType == LengthTypePercentage)
- return m_valueInSpecifiedUnits;
+ if (m_value->isPercentage())
+ return m_value->getFloatValue();
- return m_valueInSpecifiedUnits * 100;
+ return m_value->getFloatValue() * 100;
}
float SVGLength::scaleByPercentage(float input) const
{
- float result = input * m_valueInSpecifiedUnits;
- if (m_unitType == LengthTypePercentage) {
+ float result = input * m_value->getFloatValue();
+ if (m_value->isPercentage()) {
// Delaying division by 100 as long as possible since it introduces floating point errors.
result = result / 100;
}
return result;
}
-template<typename CharType>
-static bool parseValueInternal(const String& string, float& convertedNumber, SVGLengthType& type)
-{
- const CharType* ptr = string.getCharacters<CharType>();
- const CharType* end = ptr + string.length();
-
- if (!parseNumber(ptr, end, convertedNumber, AllowLeadingWhitespace))
- return false;
-
- type = stringToLengthType(ptr, end);
- ASSERT(ptr <= end);
- if (type == LengthTypeUnknown)
- return false;
-
- return true;
-}
-
void SVGLength::setValueAsString(const String& string, ExceptionState& exceptionState)
{
if (string.isEmpty()) {
- m_unitType = LengthTypeNumber;
- m_valueInSpecifiedUnits = 0;
+ m_value = cssValuePool().createValue(0, CSSPrimitiveValue::UnitType::UserUnits);
return;
}
- float convertedNumber = 0;
- SVGLengthType type = LengthTypeUnknown;
-
- bool success = string.is8Bit() ?
- parseValueInternal<LChar>(string, convertedNumber, type) :
- parseValueInternal<UChar>(string, convertedNumber, type);
+ CSSParserContext svgParserContext(SVGAttributeMode, 0);
+ RefPtrWillBeRawPtr<CSSValue> parsed = CSSParser::parseSingleValue(CSSPropertyX, string, svgParserContext);
+ if (!parsed || !parsed->isPrimitiveValue()) {
+ exceptionState.throwDOMException(SyntaxError, "The value provided ('" + string + "') is invalid.");
+ return;
+ }
- if (!success) {
+ CSSPrimitiveValue* newValue = toCSSPrimitiveValue(parsed.get());
+ // TODO(fs): Enable calc for SVG lengths
+ if (newValue->isCalculated() || !isSupportedCSSUnitType(newValue->typeWithCalcResolved())) {
exceptionState.throwDOMException(SyntaxError, "The value provided ('" + string + "') is invalid.");
return;
}
- m_unitType = type;
- m_valueInSpecifiedUnits = convertedNumber;
+ m_value = newValue;
}
String SVGLength::valueAsString() const
{
- return String::number(m_valueInSpecifiedUnits) + lengthTypeToString(unitType());
+ return m_value->customCSSText();
}
-void SVGLength::newValueSpecifiedUnits(SVGLengthType type, float value)
+void SVGLength::newValueSpecifiedUnits(CSSPrimitiveValue::UnitType type, float value)
{
- setUnitType(type);
- m_valueInSpecifiedUnits = value;
+ m_value = CSSPrimitiveValue::create(value, type);
}
-void SVGLength::convertToSpecifiedUnits(SVGLengthType type, const SVGLengthContext& context)
+void SVGLength::convertToSpecifiedUnits(CSSPrimitiveValue::UnitType type, const SVGLengthContext& context)
{
- ASSERT(type != LengthTypeUnknown && type <= LengthTypeCHS);
+ ASSERT(isSupportedCSSUnitType(type));
float valueInUserUnits = value(context);
- m_unitType = type;
- setValue(valueInUserUnits, context);
+ m_value = CSSPrimitiveValue::create(
+ context.convertValueFromUserUnits(valueInUserUnits, unitMode(), type),
+ type);
}
SVGLengthMode SVGLength::lengthModeForAnimatedLengthAttribute(const QualifiedName& attrName)
@@ -323,7 +228,13 @@ void SVGLength::add(PassRefPtrWillBeRawPtr<SVGPropertyBase> other, SVGElement* c
setValue(value(lengthContext) + toSVGLength(other)->value(lengthContext), lengthContext);
}
-void SVGLength::calculateAnimatedValue(SVGAnimationElement* animationElement, float percentage, unsigned repeatCount, PassRefPtrWillBeRawPtr<SVGPropertyBase> fromValue, PassRefPtrWillBeRawPtr<SVGPropertyBase> toValue, PassRefPtrWillBeRawPtr<SVGPropertyBase> toAtEndOfDurationValue, SVGElement* contextElement)
+void SVGLength::calculateAnimatedValue(SVGAnimationElement* animationElement,
+ float percentage,
+ unsigned repeatCount,
+ PassRefPtrWillBeRawPtr<SVGPropertyBase> fromValue,
+ PassRefPtrWillBeRawPtr<SVGPropertyBase> toValue,
+ PassRefPtrWillBeRawPtr<SVGPropertyBase> toAtEndOfDurationValue,
+ SVGElement* contextElement)
{
RefPtrWillBeRawPtr<SVGLength> fromLength = toSVGLength(fromValue);
RefPtrWillBeRawPtr<SVGLength> toLength = toSVGLength(toValue);
@@ -331,11 +242,14 @@ void SVGLength::calculateAnimatedValue(SVGAnimationElement* animationElement, fl
SVGLengthContext lengthContext(contextElement);
float animatedNumber = value(lengthContext);
- animationElement->animateAdditiveNumber(percentage, repeatCount, fromLength->value(lengthContext), toLength->value(lengthContext), toAtEndOfDurationLength->value(lengthContext), animatedNumber);
+ animationElement->animateAdditiveNumber(percentage, repeatCount, fromLength->value(lengthContext),
+ toLength->value(lengthContext), toAtEndOfDurationLength->value(lengthContext), animatedNumber);
ASSERT(unitMode() == lengthModeForAnimatedLengthAttribute(animationElement->attributeName()));
- m_unitType = percentage < 0.5 ? fromLength->unitType() : toLength->unitType();
- setValue(animatedNumber, lengthContext);
+
+ CSSPrimitiveValue::UnitType newUnit = percentage < 0.5 ? fromLength->typeWithCalcResolved() : toLength->typeWithCalcResolved();
+ animatedNumber = lengthContext.convertValueFromUserUnits(animatedNumber, unitMode(), newUnit);
+ m_value = CSSPrimitiveValue::create(animatedNumber, newUnit);
}
float SVGLength::calculateDistance(PassRefPtrWillBeRawPtr<SVGPropertyBase> toValue, SVGElement* contextElement)
« no previous file with comments | « third_party/WebKit/Source/core/svg/SVGLength.h ('k') | third_party/WebKit/Source/core/svg/SVGLengthContext.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698