summaryrefslogtreecommitdiff
path: root/Source/WebCore/svg/SVGLengthContext.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/svg/SVGLengthContext.cpp')
-rw-r--r--Source/WebCore/svg/SVGLengthContext.cpp152
1 files changed, 78 insertions, 74 deletions
diff --git a/Source/WebCore/svg/SVGLengthContext.cpp b/Source/WebCore/svg/SVGLengthContext.cpp
index 07b2045bf..fff1e879f 100644
--- a/Source/WebCore/svg/SVGLengthContext.cpp
+++ b/Source/WebCore/svg/SVGLengthContext.cpp
@@ -3,6 +3,7 @@
* Copyright (C) 2004, 2005, 2006, 2007 Rob Buis <buis@kde.org>
* Copyright (C) 2007 Apple Inc. All rights reserved.
* Copyright (C) Research In Motion Limited 2011. All rights reserved.
+ * Copyright (C) 2014 Adobe Systems Incorporated. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -21,18 +22,16 @@
*/
#include "config.h"
-
-#if ENABLE(SVG)
#include "SVGLengthContext.h"
#include "CSSHelper.h"
#include "ExceptionCode.h"
#include "FontMetrics.h"
#include "Frame.h"
+#include "LengthFunctions.h"
#include "RenderSVGRoot.h"
#include "RenderSVGViewportContainer.h"
#include "RenderView.h"
-#include "SVGNames.h"
#include "SVGSVGElement.h"
namespace WebCore {
@@ -48,7 +47,7 @@ SVGLengthContext::SVGLengthContext(const SVGElement* context, const FloatRect& v
{
}
-FloatRect SVGLengthContext::resolveRectangle(const SVGElement* context, SVGUnitTypes::SVGUnitType type, const FloatRect& viewport, const SVGLength& x, const SVGLength& y, const SVGLength& width, const SVGLength& height)
+FloatRect SVGLengthContext::resolveRectangle(const SVGElement* context, SVGUnitTypes::SVGUnitType type, const FloatRect& viewport, const SVGLengthValue& x, const SVGLengthValue& y, const SVGLengthValue& width, const SVGLengthValue& height)
{
ASSERT(type != SVGUnitTypes::SVG_UNIT_TYPE_UNKNOWN);
if (type == SVGUnitTypes::SVG_UNIT_TYPE_USERSPACEONUSE) {
@@ -63,7 +62,7 @@ FloatRect SVGLengthContext::resolveRectangle(const SVGElement* context, SVGUnitT
height.value(lengthContext));
}
-FloatPoint SVGLengthContext::resolvePoint(const SVGElement* context, SVGUnitTypes::SVGUnitType type, const SVGLength& x, const SVGLength& y)
+FloatPoint SVGLengthContext::resolvePoint(const SVGElement* context, SVGUnitTypes::SVGUnitType type, const SVGLengthValue& x, const SVGLengthValue& y)
{
ASSERT(type != SVGUnitTypes::SVG_UNIT_TYPE_UNKNOWN);
if (type == SVGUnitTypes::SVG_UNIT_TYPE_USERSPACEONUSE) {
@@ -75,7 +74,7 @@ FloatPoint SVGLengthContext::resolvePoint(const SVGElement* context, SVGUnitType
return FloatPoint(x.valueAsPercentage(), y.valueAsPercentage());
}
-float SVGLengthContext::resolveLength(const SVGElement* context, SVGUnitTypes::SVGUnitType type, const SVGLength& x)
+float SVGLengthContext::resolveLength(const SVGElement* context, SVGUnitTypes::SVGUnitType type, const SVGLengthValue& x)
{
ASSERT(type != SVGUnitTypes::SVG_UNIT_TYPE_UNKNOWN);
if (type == SVGUnitTypes::SVG_UNIT_TYPE_USERSPACEONUSE) {
@@ -87,30 +86,54 @@ float SVGLengthContext::resolveLength(const SVGElement* context, SVGUnitTypes::S
return x.valueAsPercentage();
}
-float SVGLengthContext::convertValueToUserUnits(float value, SVGLengthMode mode, SVGLengthType fromUnit, ExceptionCode& ec) const
+float SVGLengthContext::valueForLength(const Length& length, SVGLengthMode mode)
+{
+ if (length.isPercent()) {
+ auto result = convertValueFromPercentageToUserUnits(length.value() / 100, mode);
+ if (result.hasException())
+ return 0;
+ return result.releaseReturnValue();
+ }
+ if (length.isAuto() || !length.isSpecified())
+ return 0;
+
+ FloatSize viewportSize;
+ determineViewport(viewportSize);
+
+ switch (mode) {
+ case LengthModeWidth:
+ return floatValueForLength(length, viewportSize.width());
+ case LengthModeHeight:
+ return floatValueForLength(length, viewportSize.height());
+ case LengthModeOther:
+ return floatValueForLength(length, std::sqrt(viewportSize.diagonalLengthSquared() / 2));
+ };
+ return 0;
+}
+
+ExceptionOr<float> SVGLengthContext::convertValueToUserUnits(float value, SVGLengthMode mode, SVGLengthType fromUnit) const
{
// If the SVGLengthContext carries a custom viewport, force resolving against it.
if (!m_overridenViewport.isEmpty()) {
// 100% = 100.0 instead of 1.0 for historical reasons, this could eventually be changed
if (fromUnit == LengthTypePercentage)
value /= 100;
- return convertValueFromPercentageToUserUnits(value, mode, ec);
+ return convertValueFromPercentageToUserUnits(value, mode);
}
switch (fromUnit) {
case LengthTypeUnknown:
- ec = NOT_SUPPORTED_ERR;
- return 0;
+ return Exception { NOT_SUPPORTED_ERR };
case LengthTypeNumber:
return value;
case LengthTypePX:
return value;
case LengthTypePercentage:
- return convertValueFromPercentageToUserUnits(value / 100, mode, ec);
+ return convertValueFromPercentageToUserUnits(value / 100, mode);
case LengthTypeEMS:
- return convertValueFromEMSToUserUnits(value, ec);
+ return convertValueFromEMSToUserUnits(value);
case LengthTypeEXS:
- return convertValueFromEXSToUserUnits(value, ec);
+ return convertValueFromEXSToUserUnits(value);
case LengthTypeCM:
return value * cssPixelsPerInch / 2.54f;
case LengthTypeMM:
@@ -127,20 +150,19 @@ float SVGLengthContext::convertValueToUserUnits(float value, SVGLengthMode mode,
return 0;
}
-float SVGLengthContext::convertValueFromUserUnits(float value, SVGLengthMode mode, SVGLengthType toUnit, ExceptionCode& ec) const
+ExceptionOr<float> SVGLengthContext::convertValueFromUserUnits(float value, SVGLengthMode mode, SVGLengthType toUnit) const
{
switch (toUnit) {
case LengthTypeUnknown:
- ec = NOT_SUPPORTED_ERR;
- return 0;
+ return Exception { NOT_SUPPORTED_ERR };
case LengthTypeNumber:
return value;
case LengthTypePercentage:
- return convertValueFromUserUnitsToPercentage(value * 100, mode, ec);
+ return convertValueFromUserUnitsToPercentage(value * 100, mode);
case LengthTypeEMS:
- return convertValueFromUserUnitsToEMS(value, ec);
+ return convertValueFromUserUnitsToEMS(value);
case LengthTypeEXS:
- return convertValueFromUserUnitsToEXS(value, ec);
+ return convertValueFromUserUnitsToEXS(value);
case LengthTypePX:
return value;
case LengthTypeCM:
@@ -159,13 +181,11 @@ float SVGLengthContext::convertValueFromUserUnits(float value, SVGLengthMode mod
return 0;
}
-float SVGLengthContext::convertValueFromUserUnitsToPercentage(float value, SVGLengthMode mode, ExceptionCode& ec) const
+ExceptionOr<float> SVGLengthContext::convertValueFromUserUnitsToPercentage(float value, SVGLengthMode mode) const
{
FloatSize viewportSize;
- if (!determineViewport(viewportSize)) {
- ec = NOT_SUPPORTED_ERR;
- return 0;
- }
+ if (!determineViewport(viewportSize))
+ return Exception { NOT_SUPPORTED_ERR };
switch (mode) {
case LengthModeWidth:
@@ -173,20 +193,18 @@ float SVGLengthContext::convertValueFromUserUnitsToPercentage(float value, SVGLe
case LengthModeHeight:
return value / viewportSize.height() * 100;
case LengthModeOther:
- return value / (sqrtf(viewportSize.diagonalLengthSquared() / 2)) * 100;
+ return value / (std::sqrt(viewportSize.diagonalLengthSquared() / 2)) * 100;
};
ASSERT_NOT_REACHED();
return 0;
}
-float SVGLengthContext::convertValueFromPercentageToUserUnits(float value, SVGLengthMode mode, ExceptionCode& ec) const
+ExceptionOr<float> SVGLengthContext::convertValueFromPercentageToUserUnits(float value, SVGLengthMode mode) const
{
FloatSize viewportSize;
- if (!determineViewport(viewportSize)) {
- ec = NOT_SUPPORTED_ERR;
- return 0;
- }
+ if (!determineViewport(viewportSize))
+ return Exception { NOT_SUPPORTED_ERR };
switch (mode) {
case LengthModeWidth:
@@ -194,14 +212,14 @@ float SVGLengthContext::convertValueFromPercentageToUserUnits(float value, SVGLe
case LengthModeHeight:
return value * viewportSize.height();
case LengthModeOther:
- return value * sqrtf(viewportSize.diagonalLengthSquared() / 2);
+ return value * std::sqrt(viewportSize.diagonalLengthSquared() / 2);
};
ASSERT_NOT_REACHED();
return 0;
}
-static inline RenderStyle* renderStyleForLengthResolving(const SVGElement* context)
+static inline const RenderStyle* renderStyleForLengthResolving(const SVGElement* context)
{
if (!context)
return nullptr;
@@ -215,67 +233,55 @@ static inline RenderStyle* renderStyleForLengthResolving(const SVGElement* conte
// There must be at least a RenderSVGRoot renderer, carrying a style.
ASSERT_NOT_REACHED();
- return 0;
+ return nullptr;
}
-float SVGLengthContext::convertValueFromUserUnitsToEMS(float value, ExceptionCode& ec) const
+ExceptionOr<float> SVGLengthContext::convertValueFromUserUnitsToEMS(float value) const
{
- RenderStyle* style = renderStyleForLengthResolving(m_context);
- if (!style) {
- ec = NOT_SUPPORTED_ERR;
- return 0;
- }
+ auto* style = renderStyleForLengthResolving(m_context);
+ if (!style)
+ return Exception { NOT_SUPPORTED_ERR };
float fontSize = style->fontSize();
- if (!fontSize) {
- ec = NOT_SUPPORTED_ERR;
- return 0;
- }
+ if (!fontSize)
+ return Exception { NOT_SUPPORTED_ERR };
return value / fontSize;
}
-float SVGLengthContext::convertValueFromEMSToUserUnits(float value, ExceptionCode& ec) const
+ExceptionOr<float> SVGLengthContext::convertValueFromEMSToUserUnits(float value) const
{
- RenderStyle* style = renderStyleForLengthResolving(m_context);
- if (!style) {
- ec = NOT_SUPPORTED_ERR;
- return 0;
- }
+ auto* style = renderStyleForLengthResolving(m_context);
+ if (!style)
+ return Exception { NOT_SUPPORTED_ERR };
return value * style->fontSize();
}
-float SVGLengthContext::convertValueFromUserUnitsToEXS(float value, ExceptionCode& ec) const
+ExceptionOr<float> SVGLengthContext::convertValueFromUserUnitsToEXS(float value) const
{
- RenderStyle* style = renderStyleForLengthResolving(m_context);
- if (!style) {
- ec = NOT_SUPPORTED_ERR;
- return 0;
- }
+ auto* style = renderStyleForLengthResolving(m_context);
+ if (!style)
+ return Exception { NOT_SUPPORTED_ERR };
// Use of ceil allows a pixel match to the W3Cs expected output of coords-units-03-b.svg
// if this causes problems in real world cases maybe it would be best to remove this
- float xHeight = ceilf(style->fontMetrics().xHeight());
- if (!xHeight) {
- ec = NOT_SUPPORTED_ERR;
- return 0;
- }
+ float xHeight = std::ceil(style->fontMetrics().xHeight());
+ if (!xHeight)
+ return Exception { NOT_SUPPORTED_ERR };
return value / xHeight;
}
-float SVGLengthContext::convertValueFromEXSToUserUnits(float value, ExceptionCode& ec) const
+ExceptionOr<float> SVGLengthContext::convertValueFromEXSToUserUnits(float value) const
{
- RenderStyle* style = renderStyleForLengthResolving(m_context);
- if (!style) {
- ec = NOT_SUPPORTED_ERR;
- return 0;
- }
+ auto* style = renderStyleForLengthResolving(m_context);
+ if (!style)
+ return Exception { NOT_SUPPORTED_ERR };
// Use of ceil allows a pixel match to the W3Cs expected output of coords-units-03-b.svg
// if this causes problems in real world cases maybe it would be best to remove this
- return value * ceilf(style->fontMetrics().xHeight());
+ return value * std::ceil(style->fontMetrics().xHeight());
}
bool SVGLengthContext::determineViewport(FloatSize& viewportSize) const
@@ -291,23 +297,21 @@ bool SVGLengthContext::determineViewport(FloatSize& viewportSize) const
// Root <svg> element lengths are resolved against the top level viewport.
if (m_context->isOutermostSVGSVGElement()) {
- viewportSize = toSVGSVGElement(m_context)->currentViewportSize();
+ viewportSize = downcast<SVGSVGElement>(*m_context).currentViewportSize();
return true;
}
// Take size from nearest viewport element.
SVGElement* viewportElement = m_context->viewportElement();
- if (!viewportElement || !isSVGSVGElement(viewportElement))
+ if (!is<SVGSVGElement>(viewportElement))
return false;
- const SVGSVGElement* svg = toSVGSVGElement(viewportElement);
- viewportSize = svg->currentViewBoxRect().size();
+ const SVGSVGElement& svg = downcast<SVGSVGElement>(*viewportElement);
+ viewportSize = svg.currentViewBoxRect().size();
if (viewportSize.isEmpty())
- viewportSize = svg->currentViewportSize();
+ viewportSize = svg.currentViewportSize();
return true;
}
}
-
-#endif