Changeset 226373 in webkit
- Timestamp:
- Jan 3, 2018 1:56:00 PM (6 years ago)
- Location:
- trunk
- Files:
-
- 6 added
- 14 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r226372 r226373 1 2018-01-03 Simon Fraser <simon.fraser@apple.com> 2 3 feLighting is broken with primitiveUnits="objectBoundingBox" 4 https://bugs.webkit.org/show_bug.cgi?id=181197 5 6 Reviewed by Tim Horton. 7 8 Ref tests with primitiveUnits=objectBoundingBox for feSpotLight and fePointLight. 9 10 * svg/filters/feDiffuseLighting-fePointLight-primitiveUnits-objectBoundingBox-expected.svg: Added. 11 * svg/filters/feDiffuseLighting-fePointLight-primitiveUnits-objectBoundingBox.svg: Added. 12 * svg/filters/feDiffuseLighting-feSpotLight-primitiveUnits-objectBoundingBox-expected.svg: Added. 13 * svg/filters/feDiffuseLighting-feSpotLight-primitiveUnits-objectBoundingBox.svg: Added. 14 * svg/filters/feSpecularLighting-fePointLight-primitiveUnits-objectBoundingBox-expected.svg: Added. 15 * svg/filters/feSpecularLighting-fePointLight-primitiveUnits-objectBoundingBox.svg: Added. 16 1 17 2018-01-03 Antti Koivisto <antti@apple.com> 2 18 -
trunk/Source/WebCore/ChangeLog
r226372 r226373 1 2018-01-03 Simon Fraser <simon.fraser@apple.com> 2 3 feLighting is broken with primitiveUnits="objectBoundingBox" 4 https://bugs.webkit.org/show_bug.cgi?id=181197 5 6 Reviewed by Tim Horton. 7 8 With <filter primitiveUnits="objectBoundingBox"> we need to convert the coordinates 9 of fePointLights and feSpotLights into user space coordinates. Following 10 https://www.w3.org/TR/SVG/filters.html#FilterElementPrimitiveUnitsAttribute 11 this is done by treating them as fractions of the bounding box on the referencing 12 element, with treatment for z following https://www.w3.org/TR/SVG/coords.html#Units_viewport_percentage 13 14 To do this, store the bounds of the referencing elemenet on SVGFilterBuilder as 15 targetBoundingBox, and store the primitiveUnits type. Then do the conversion of lighting 16 coordinates in SVGFESpecularLightingElement::build() and SVGFEDiffuseLightingElement::build(). 17 18 Remove SVGFELightElement::findLightSource(), since we need to be able to pass the SVGFilterBuilder 19 to the lightSource() function so hoist the code up. 20 21 Tests: svg/filters/feDiffuseLighting-fePointLight-primitiveUnits-objectBoundingBox-expected.svg 22 svg/filters/feDiffuseLighting-fePointLight-primitiveUnits-objectBoundingBox.svg 23 svg/filters/feDiffuseLighting-feSpotLight-primitiveUnits-objectBoundingBox-expected.svg 24 svg/filters/feDiffuseLighting-feSpotLight-primitiveUnits-objectBoundingBox.svg 25 svg/filters/feSpecularLighting-fePointLight-primitiveUnits-objectBoundingBox-expected.svg 26 svg/filters/feSpecularLighting-fePointLight-primitiveUnits-objectBoundingBox.svg 27 28 * rendering/svg/RenderSVGResourceFilter.cpp: 29 (WebCore::RenderSVGResourceFilter::buildPrimitives const): 30 * svg/SVGFEDiffuseLightingElement.cpp: 31 (WebCore::SVGFEDiffuseLightingElement::build): 32 * svg/SVGFEDistantLightElement.cpp: 33 (WebCore::SVGFEDistantLightElement::lightSource const): 34 * svg/SVGFEDistantLightElement.h: 35 * svg/SVGFELightElement.cpp: 36 (WebCore::SVGFELightElement::findLightSource): Deleted. 37 * svg/SVGFELightElement.h: 38 * svg/SVGFEPointLightElement.cpp: 39 (WebCore::SVGFEPointLightElement::lightSource const): 40 * svg/SVGFEPointLightElement.h: 41 * svg/SVGFESpecularLightingElement.cpp: 42 (WebCore::SVGFESpecularLightingElement::build): 43 * svg/SVGFESpotLightElement.cpp: 44 (WebCore::SVGFESpotLightElement::lightSource const): 45 * svg/SVGFESpotLightElement.h: 46 * svg/graphics/filters/SVGFilterBuilder.h: 47 (WebCore::SVGFilterBuilder::setTargetBoundingBox): 48 (WebCore::SVGFilterBuilder::targetBoundingBox const): 49 (WebCore::SVGFilterBuilder::primitiveUnits const): 50 (WebCore::SVGFilterBuilder::setPrimitiveUnits): 51 1 52 2018-01-03 Antti Koivisto <antti@apple.com> 2 53 -
trunk/Source/WebCore/rendering/svg/RenderSVGResourceFilter.cpp
r225797 r226373 90 90 // Add effects to the builder 91 91 auto builder = std::make_unique<SVGFilterBuilder>(SourceGraphic::create(filter)); 92 builder->setPrimitiveUnits(filterElement().primitiveUnits()); 93 builder->setTargetBoundingBox(targetBoundingBox); 94 92 95 for (auto& element : childrenOfType<SVGFilterPrimitiveStandardAttributes>(filterElement())) { 93 96 RefPtr<FilterEffect> effect = element.build(builder.get(), filter); -
trunk/Source/WebCore/svg/SVGFEDiffuseLightingElement.cpp
r224615 r226373 178 178 return nullptr; 179 179 180 auto light Source = SVGFELightElement::findLightSource(this);181 if (!light Source)180 auto lightElement = makeRefPtr(SVGFELightElement::findLightElement(this)); 181 if (!lightElement) 182 182 return nullptr; 183 184 auto lightSource = lightElement->lightSource(*filterBuilder); 183 185 184 186 RenderObject* renderer = this->renderer(); … … 188 190 const Color& color = renderer->style().svgStyle().lightingColor(); 189 191 190 RefPtr<FilterEffect> effect = FEDiffuseLighting::create(filter, color, surfaceScale(), diffuseConstant(), kernelUnitLengthX(), kernelUnitLengthY(), lightSource.releaseNonNull());192 RefPtr<FilterEffect> effect = FEDiffuseLighting::create(filter, color, surfaceScale(), diffuseConstant(), kernelUnitLengthX(), kernelUnitLengthY(), WTFMove(lightSource)); 191 193 effect->inputEffects().append(input1); 192 194 return effect; -
trunk/Source/WebCore/svg/SVGFEDistantLightElement.cpp
r183611 r226373 37 37 } 38 38 39 Ref<LightSource> SVGFEDistantLightElement::lightSource( ) const39 Ref<LightSource> SVGFEDistantLightElement::lightSource(SVGFilterBuilder&) const 40 40 { 41 41 return DistantLightSource::create(azimuth(), elevation()); -
trunk/Source/WebCore/svg/SVGFEDistantLightElement.h
r208668 r226373 31 31 SVGFEDistantLightElement(const QualifiedName&, Document&); 32 32 33 Ref<LightSource> lightSource( ) const override;33 Ref<LightSource> lightSource(SVGFilterBuilder&) const override; 34 34 }; 35 35 -
trunk/Source/WebCore/svg/SVGFELightElement.cpp
r224615 r226373 76 76 } 77 77 return nullptr; 78 }79 80 RefPtr<LightSource> SVGFELightElement::findLightSource(const SVGElement* svgElement)81 {82 auto lightNode = makeRefPtr(findLightElement(svgElement));83 if (!lightNode)84 return 0;85 return lightNode->lightSource();86 78 } 87 79 -
trunk/Source/WebCore/svg/SVGFELightElement.h
r208668 r226373 28 28 namespace WebCore { 29 29 30 class SVGFilterBuilder; 31 30 32 class SVGFELightElement : public SVGElement { 31 33 public: 32 virtual Ref<LightSource> lightSource( ) const = 0;34 virtual Ref<LightSource> lightSource(SVGFilterBuilder&) const = 0; 33 35 static SVGFELightElement* findLightElement(const SVGElement*); 34 static RefPtr<LightSource> findLightSource(const SVGElement*);35 36 36 37 protected: -
trunk/Source/WebCore/svg/SVGFEPointLightElement.cpp
r183611 r226373 20 20 #include "config.h" 21 21 #include "SVGFEPointLightElement.h" 22 23 #include "GeometryUtilities.h" 24 #include "PointLightSource.h" 25 #include "SVGFilterBuilder.h" 22 26 #include "SVGNames.h" 23 24 #include "PointLightSource.h" 27 #include <wtf/MathExtras.h> 25 28 26 29 namespace WebCore { … … 37 40 } 38 41 39 Ref<LightSource> SVGFEPointLightElement::lightSource( ) const42 Ref<LightSource> SVGFEPointLightElement::lightSource(SVGFilterBuilder& builder) const 40 43 { 41 return PointLightSource::create(FloatPoint3D(x(), y(), z())); 44 FloatPoint3D position; 45 if (builder.primitiveUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) { 46 FloatRect referenceBox = builder.targetBoundingBox(); 47 48 position.setX(referenceBox.x() + x() * referenceBox.width()); 49 position.setY(referenceBox.y() + y() * referenceBox.height()); 50 51 // https://www.w3.org/TR/SVG/filters.html#fePointLightZAttribute and https://www.w3.org/TR/SVG/coords.html#Units_viewport_percentage 52 position.setZ(z() * euclidianDistance(referenceBox.minXMinYCorner(), referenceBox.maxXMaxYCorner()) / sqrtOfTwoFloat); 53 } else 54 position = FloatPoint3D(x(), y(), z()); 55 56 return PointLightSource::create(position); 42 57 } 43 58 -
trunk/Source/WebCore/svg/SVGFEPointLightElement.h
r208668 r226373 31 31 SVGFEPointLightElement(const QualifiedName&, Document&); 32 32 33 Ref<LightSource> lightSource( ) const override;33 Ref<LightSource> lightSource(SVGFilterBuilder&) const override; 34 34 }; 35 35 -
trunk/Source/WebCore/svg/SVGFESpecularLightingElement.cpp
r224615 r226373 189 189 return nullptr; 190 190 191 auto light Source = SVGFELightElement::findLightSource(this);192 if (!light Source)191 auto lightElement = makeRefPtr(SVGFELightElement::findLightElement(this)); 192 if (!lightElement) 193 193 return nullptr; 194 195 auto lightSource = lightElement->lightSource(*filterBuilder); 194 196 195 197 RenderObject* renderer = this->renderer(); … … 199 201 const Color& color = renderer->style().svgStyle().lightingColor(); 200 202 201 RefPtr<FilterEffect> effect = FESpecularLighting::create(filter, color, surfaceScale(), specularConstant(), specularExponent(), kernelUnitLengthX(), kernelUnitLengthY(), lightSource.releaseNonNull());203 RefPtr<FilterEffect> effect = FESpecularLighting::create(filter, color, surfaceScale(), specularConstant(), specularExponent(), kernelUnitLengthX(), kernelUnitLengthY(), WTFMove(lightSource)); 202 204 effect->inputEffects().append(input1); 203 205 return effect; -
trunk/Source/WebCore/svg/SVGFESpotLightElement.cpp
r183611 r226373 21 21 #include "SVGFESpotLightElement.h" 22 22 23 #include "GeometryUtilities.h" 24 #include "SVGFilterBuilder.h" 23 25 #include "SVGNames.h" 24 26 #include "SpotLightSource.h" 27 #include <wtf/MathExtras.h> 25 28 26 29 namespace WebCore { … … 37 40 } 38 41 39 Ref<LightSource> SVGFESpotLightElement::lightSource( ) const42 Ref<LightSource> SVGFESpotLightElement::lightSource(SVGFilterBuilder& builder) const 40 43 { 41 FloatPoint3D pos (x(), y(), z());42 FloatPoint3D direction(pointsAtX(), pointsAtY(), pointsAtZ());44 FloatPoint3D position; 45 FloatPoint3D pointsAt; 43 46 44 return SpotLightSource::create(pos, direction, specularExponent(), limitingConeAngle()); 47 if (builder.primitiveUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) { 48 FloatRect referenceBox = builder.targetBoundingBox(); 49 50 position.setX(referenceBox.x() + x() * referenceBox.width()); 51 position.setY(referenceBox.y() + y() * referenceBox.height()); 52 // https://www.w3.org/TR/SVG/filters.html#fePointLightZAttribute and https://www.w3.org/TR/SVG/coords.html#Units_viewport_percentage 53 position.setZ(z() * euclidianDistance(referenceBox.minXMinYCorner(), referenceBox.maxXMaxYCorner()) / sqrtOfTwoFloat); 54 55 pointsAt.setX(referenceBox.x() + pointsAtX() * referenceBox.width()); 56 pointsAt.setY(referenceBox.y() + pointsAtY() * referenceBox.height()); 57 // https://www.w3.org/TR/SVG/filters.html#fePointLightZAttribute and https://www.w3.org/TR/SVG/coords.html#Units_viewport_percentage 58 pointsAt.setZ(pointsAtZ() * euclidianDistance(referenceBox.minXMinYCorner(), referenceBox.maxXMaxYCorner()) / sqrtOfTwoFloat); 59 } else { 60 position = FloatPoint3D(x(), y(), z()); 61 pointsAt = FloatPoint3D(pointsAtX(), pointsAtY(), pointsAtZ()); 62 } 63 64 return SpotLightSource::create(position, pointsAt, specularExponent(), limitingConeAngle()); 45 65 } 46 66 -
trunk/Source/WebCore/svg/SVGFESpotLightElement.h
r208668 r226373 31 31 SVGFESpotLightElement(const QualifiedName&, Document&); 32 32 33 Ref<LightSource> lightSource( ) const override;33 Ref<LightSource> lightSource(SVGFilterBuilder&) const override; 34 34 }; 35 35 -
trunk/Source/WebCore/svg/graphics/filters/SVGFilterBuilder.h
r224615 r226373 22 22 23 23 #include "FilterEffect.h" 24 #include "SVGUnitTypes.h" 24 25 #include <wtf/HashMap.h> 25 26 #include <wtf/HashSet.h> … … 30 31 31 32 class RenderObject; 33 class SVGFilterElement; 32 34 33 35 class SVGFilterBuilder { … … 36 38 37 39 SVGFilterBuilder(RefPtr<FilterEffect> sourceGraphic); 40 41 void setTargetBoundingBox(const FloatRect& r) { m_targetBoundingBox = r; } 42 FloatRect targetBoundingBox() const { return m_targetBoundingBox; } 43 44 SVGUnitTypes::SVGUnitType primitiveUnits() const { return m_primitiveUnits; } 45 void setPrimitiveUnits(SVGUnitTypes::SVGUnitType units) { m_primitiveUnits = units; } 38 46 39 47 void add(const AtomicString& id, RefPtr<FilterEffect>); … … 72 80 73 81 RefPtr<FilterEffect> m_lastEffect; 82 FloatRect m_targetBoundingBox; 83 SVGUnitTypes::SVGUnitType m_primitiveUnits { SVGUnitTypes::SVG_UNIT_TYPE_USERSPACEONUSE }; 74 84 }; 75 85
Note: See TracChangeset
for help on using the changeset viewer.