| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2004, 2005, 2006 Nikolas Zimmermann <zimmermann@kde.org> | 2 * Copyright (C) 2004, 2005, 2006 Nikolas Zimmermann <zimmermann@kde.org> |
| 3 * Copyright (C) 2004, 2005, 2006, 2007 Rob Buis <buis@kde.org> | 3 * Copyright (C) 2004, 2005, 2006, 2007 Rob Buis <buis@kde.org> |
| 4 * Copyright (C) 2007 Apple Inc. All rights reserved. | 4 * Copyright (C) 2007 Apple Inc. All rights reserved. |
| 5 * Copyright (C) Research In Motion Limited 2011. All rights reserved. | 5 * Copyright (C) Research In Motion Limited 2011. All rights reserved. |
| 6 * | 6 * |
| 7 * This library is free software; you can redistribute it and/or | 7 * This library is free software; you can redistribute it and/or |
| 8 * modify it under the terms of the GNU Library General Public | 8 * modify it under the terms of the GNU Library General Public |
| 9 * License as published by the Free Software Foundation; either | 9 * License as published by the Free Software Foundation; either |
| 10 * version 2 of the License, or (at your option) any later version. | 10 * version 2 of the License, or (at your option) any later version. |
| (...skipping 23 matching lines...) Expand all Loading... |
| 34 #include "core/svg/SVGSVGElement.h" | 34 #include "core/svg/SVGSVGElement.h" |
| 35 #include "platform/fonts/FontMetrics.h" | 35 #include "platform/fonts/FontMetrics.h" |
| 36 | 36 |
| 37 namespace blink { | 37 namespace blink { |
| 38 | 38 |
| 39 SVGLengthContext::SVGLengthContext(const SVGElement* context) | 39 SVGLengthContext::SVGLengthContext(const SVGElement* context) |
| 40 : m_context(context) | 40 : m_context(context) |
| 41 { | 41 { |
| 42 } | 42 } |
| 43 | 43 |
| 44 SVGLengthContext::SVGLengthContext(const SVGElement* context, const FloatRect& v
iewport) | 44 static float valueInSpecifiedUnitsWithPercentAdjustment(const SVGLength& length) |
| 45 : m_context(context) | |
| 46 , m_overridenViewport(viewport) | |
| 47 { | 45 { |
| 46 // 100% = 100.0 instead of 1.0 for historical reasons. |
| 47 if (length.unitType() == LengthTypePercentage) |
| 48 return length.valueInSpecifiedUnits() / 100; |
| 49 return length.valueInSpecifiedUnits(); |
| 48 } | 50 } |
| 49 | 51 |
| 50 FloatRect SVGLengthContext::resolveRectangle(const SVGElement* context, SVGUnitT
ypes::SVGUnitType type, const FloatRect& viewport, PassRefPtrWillBeRawPtr<SVGLen
gth> passX, PassRefPtrWillBeRawPtr<SVGLength> passY, PassRefPtrWillBeRawPtr<SVGL
ength> passWidth, PassRefPtrWillBeRawPtr<SVGLength> passHeight) | 52 FloatRect SVGLengthContext::resolveRectangle(const SVGElement* context, SVGUnitT
ypes::SVGUnitType type, const FloatRect& viewport, PassRefPtrWillBeRawPtr<SVGLen
gth> passX, PassRefPtrWillBeRawPtr<SVGLength> passY, PassRefPtrWillBeRawPtr<SVGL
ength> passWidth, PassRefPtrWillBeRawPtr<SVGLength> passHeight) |
| 51 { | 53 { |
| 52 RefPtrWillBeRawPtr<SVGLength> x = passX; | 54 RefPtrWillBeRawPtr<SVGLength> x = passX; |
| 53 RefPtrWillBeRawPtr<SVGLength> y = passY; | 55 RefPtrWillBeRawPtr<SVGLength> y = passY; |
| 54 RefPtrWillBeRawPtr<SVGLength> width = passWidth; | 56 RefPtrWillBeRawPtr<SVGLength> width = passWidth; |
| 55 RefPtrWillBeRawPtr<SVGLength> height = passHeight; | 57 RefPtrWillBeRawPtr<SVGLength> height = passHeight; |
| 56 | 58 |
| 57 ASSERT(type != SVGUnitTypes::SVG_UNIT_TYPE_UNKNOWN); | 59 ASSERT(type != SVGUnitTypes::SVG_UNIT_TYPE_UNKNOWN); |
| 58 if (type == SVGUnitTypes::SVG_UNIT_TYPE_USERSPACEONUSE) { | 60 if (type != SVGUnitTypes::SVG_UNIT_TYPE_USERSPACEONUSE && !viewport.isEmpty(
)) { |
| 59 SVGLengthContext lengthContext(context); | 61 const FloatSize& viewportSize = viewport.size(); |
| 60 return FloatRect(x->value(lengthContext), y->value(lengthContext), width
->value(lengthContext), height->value(lengthContext)); | 62 return FloatRect( |
| 63 convertValueFromPercentageToUserUnits(valueInSpecifiedUnitsWithPerce
ntAdjustment(*x), x->unitMode(), viewportSize) + viewport.x(), |
| 64 convertValueFromPercentageToUserUnits(valueInSpecifiedUnitsWithPerce
ntAdjustment(*y), y->unitMode(), viewportSize) + viewport.y(), |
| 65 convertValueFromPercentageToUserUnits(valueInSpecifiedUnitsWithPerce
ntAdjustment(*width), width->unitMode(), viewportSize), |
| 66 convertValueFromPercentageToUserUnits(valueInSpecifiedUnitsWithPerce
ntAdjustment(*height), height->unitMode(), viewportSize)); |
| 61 } | 67 } |
| 62 | 68 |
| 63 SVGLengthContext lengthContext(context, viewport); | 69 SVGLengthContext lengthContext(context); |
| 64 return FloatRect( | 70 return FloatRect(x->value(lengthContext), y->value(lengthContext), width->va
lue(lengthContext), height->value(lengthContext)); |
| 65 x->value(lengthContext) + viewport.x(), | |
| 66 y->value(lengthContext) + viewport.y(), | |
| 67 width->value(lengthContext), | |
| 68 height->value(lengthContext)); | |
| 69 } | 71 } |
| 70 | 72 |
| 71 FloatPoint SVGLengthContext::resolvePoint(const SVGElement* context, SVGUnitType
s::SVGUnitType type, PassRefPtrWillBeRawPtr<SVGLength> passX, PassRefPtrWillBeRa
wPtr<SVGLength> passY) | 73 FloatPoint SVGLengthContext::resolvePoint(const SVGElement* context, SVGUnitType
s::SVGUnitType type, PassRefPtrWillBeRawPtr<SVGLength> passX, PassRefPtrWillBeRa
wPtr<SVGLength> passY) |
| 72 { | 74 { |
| 73 RefPtrWillBeRawPtr<SVGLength> x = passX; | 75 RefPtrWillBeRawPtr<SVGLength> x = passX; |
| 74 RefPtrWillBeRawPtr<SVGLength> y = passY; | 76 RefPtrWillBeRawPtr<SVGLength> y = passY; |
| 75 | 77 |
| 76 ASSERT(type != SVGUnitTypes::SVG_UNIT_TYPE_UNKNOWN); | 78 ASSERT(type != SVGUnitTypes::SVG_UNIT_TYPE_UNKNOWN); |
| 77 if (type == SVGUnitTypes::SVG_UNIT_TYPE_USERSPACEONUSE) { | 79 if (type == SVGUnitTypes::SVG_UNIT_TYPE_USERSPACEONUSE) { |
| 78 SVGLengthContext lengthContext(context); | 80 SVGLengthContext lengthContext(context); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 92 SVGLengthContext lengthContext(context); | 94 SVGLengthContext lengthContext(context); |
| 93 return x->value(lengthContext); | 95 return x->value(lengthContext); |
| 94 } | 96 } |
| 95 | 97 |
| 96 // FIXME: valueAsPercentage() won't be correct for eg. cm units. They need t
o be resolved in user space and then be considered in objectBoundingBox space. | 98 // FIXME: valueAsPercentage() won't be correct for eg. cm units. They need t
o be resolved in user space and then be considered in objectBoundingBox space. |
| 97 return x->valueAsPercentage(); | 99 return x->valueAsPercentage(); |
| 98 } | 100 } |
| 99 | 101 |
| 100 float SVGLengthContext::convertValueToUserUnits(float value, SVGLengthMode mode,
SVGLengthType fromUnit, ExceptionState& exceptionState) const | 102 float SVGLengthContext::convertValueToUserUnits(float value, SVGLengthMode mode,
SVGLengthType fromUnit, ExceptionState& exceptionState) const |
| 101 { | 103 { |
| 102 // If the SVGLengthContext carries a custom viewport, force resolving agains
t it. | |
| 103 if (!m_overridenViewport.isEmpty()) { | |
| 104 // 100% = 100.0 instead of 1.0 for historical reasons, this could eventu
ally be changed | |
| 105 if (fromUnit == LengthTypePercentage) | |
| 106 value /= 100; | |
| 107 return convertValueFromPercentageToUserUnits(value, mode, exceptionState
); | |
| 108 } | |
| 109 | |
| 110 switch (fromUnit) { | 104 switch (fromUnit) { |
| 111 case LengthTypeUnknown: | 105 case LengthTypeUnknown: |
| 112 exceptionState.throwDOMException(NotSupportedError, ExceptionMessages::a
rgumentNullOrIncorrectType(3, "SVGLengthType")); | 106 exceptionState.throwDOMException(NotSupportedError, ExceptionMessages::a
rgumentNullOrIncorrectType(3, "SVGLengthType")); |
| 113 return 0; | 107 return 0; |
| 114 case LengthTypeNumber: | 108 case LengthTypeNumber: |
| 115 return value; | 109 return value; |
| 116 case LengthTypePX: | 110 case LengthTypePX: |
| 117 return value; | 111 return value; |
| 118 case LengthTypePercentage: | 112 case LengthTypePercentage: |
| 119 return convertValueFromPercentageToUserUnits(value / 100, mode, exceptio
nState); | 113 return convertValueFromPercentageToUserUnits(value / 100, mode, exceptio
nState); |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 190 return 0; | 184 return 0; |
| 191 } | 185 } |
| 192 | 186 |
| 193 float SVGLengthContext::convertValueFromPercentageToUserUnits(float value, SVGLe
ngthMode mode, ExceptionState& exceptionState) const | 187 float SVGLengthContext::convertValueFromPercentageToUserUnits(float value, SVGLe
ngthMode mode, ExceptionState& exceptionState) const |
| 194 { | 188 { |
| 195 FloatSize viewportSize; | 189 FloatSize viewportSize; |
| 196 if (!determineViewport(viewportSize)) { | 190 if (!determineViewport(viewportSize)) { |
| 197 exceptionState.throwDOMException(NotSupportedError, "The viewport could
not be determined."); | 191 exceptionState.throwDOMException(NotSupportedError, "The viewport could
not be determined."); |
| 198 return 0; | 192 return 0; |
| 199 } | 193 } |
| 194 return convertValueFromPercentageToUserUnits(value, mode, viewportSize); |
| 195 } |
| 200 | 196 |
| 197 float SVGLengthContext::convertValueFromPercentageToUserUnits(float value, SVGLe
ngthMode mode, const FloatSize& viewportSize) |
| 198 { |
| 201 switch (mode) { | 199 switch (mode) { |
| 202 case LengthModeWidth: | 200 case LengthModeWidth: |
| 203 return value * viewportSize.width(); | 201 return value * viewportSize.width(); |
| 204 case LengthModeHeight: | 202 case LengthModeHeight: |
| 205 return value * viewportSize.height(); | 203 return value * viewportSize.height(); |
| 206 case LengthModeOther: | 204 case LengthModeOther: |
| 207 return value * sqrtf(viewportSize.diagonalLengthSquared() / 2); | 205 return value * sqrtf(viewportSize.diagonalLengthSquared() / 2); |
| 208 }; | 206 }; |
| 209 | 207 |
| 210 ASSERT_NOT_REACHED(); | 208 ASSERT_NOT_REACHED(); |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 286 // Use of ceil allows a pixel match to the W3Cs expected output of coords-un
its-03-b.svg | 284 // Use of ceil allows a pixel match to the W3Cs expected output of coords-un
its-03-b.svg |
| 287 // if this causes problems in real world cases maybe it would be best to rem
ove this | 285 // if this causes problems in real world cases maybe it would be best to rem
ove this |
| 288 return value * ceilf(style->fontMetrics().xHeight()); | 286 return value * ceilf(style->fontMetrics().xHeight()); |
| 289 } | 287 } |
| 290 | 288 |
| 291 bool SVGLengthContext::determineViewport(FloatSize& viewportSize) const | 289 bool SVGLengthContext::determineViewport(FloatSize& viewportSize) const |
| 292 { | 290 { |
| 293 if (!m_context) | 291 if (!m_context) |
| 294 return false; | 292 return false; |
| 295 | 293 |
| 296 // If an overriden viewport is given, it has precedence. | |
| 297 if (!m_overridenViewport.isEmpty()) { | |
| 298 viewportSize = m_overridenViewport.size(); | |
| 299 return true; | |
| 300 } | |
| 301 | |
| 302 // Root <svg> element lengths are resolved against the top level viewport. | 294 // Root <svg> element lengths are resolved against the top level viewport. |
| 303 if (m_context->isOutermostSVGSVGElement()) { | 295 if (m_context->isOutermostSVGSVGElement()) { |
| 304 viewportSize = toSVGSVGElement(m_context)->currentViewportSize(); | 296 viewportSize = toSVGSVGElement(m_context)->currentViewportSize(); |
| 305 return true; | 297 return true; |
| 306 } | 298 } |
| 307 | 299 |
| 308 // Take size from nearest viewport element. | 300 // Take size from nearest viewport element. |
| 309 SVGElement* viewportElement = m_context->viewportElement(); | 301 SVGElement* viewportElement = m_context->viewportElement(); |
| 310 if (!isSVGSVGElement(viewportElement)) | 302 if (!isSVGSVGElement(viewportElement)) |
| 311 return false; | 303 return false; |
| 312 | 304 |
| 313 const SVGSVGElement& svg = toSVGSVGElement(*viewportElement); | 305 const SVGSVGElement& svg = toSVGSVGElement(*viewportElement); |
| 314 viewportSize = svg.currentViewBoxRect().size(); | 306 viewportSize = svg.currentViewBoxRect().size(); |
| 315 if (viewportSize.isEmpty()) | 307 if (viewportSize.isEmpty()) |
| 316 viewportSize = svg.currentViewportSize(); | 308 viewportSize = svg.currentViewportSize(); |
| 317 | 309 |
| 318 return true; | 310 return true; |
| 319 } | 311 } |
| 320 | 312 |
| 321 } | 313 } |
| OLD | NEW |