diff options
Diffstat (limited to 'Source/WebCore/svg/SVGMarkerElement.cpp')
-rw-r--r-- | Source/WebCore/svg/SVGMarkerElement.cpp | 149 |
1 files changed, 80 insertions, 69 deletions
diff --git a/Source/WebCore/svg/SVGMarkerElement.cpp b/Source/WebCore/svg/SVGMarkerElement.cpp index 40b1288b0..9fc4a7ffb 100644 --- a/Source/WebCore/svg/SVGMarkerElement.cpp +++ b/Source/WebCore/svg/SVGMarkerElement.cpp @@ -20,16 +20,12 @@ */ #include "config.h" - -#if ENABLE(SVG) #include "SVGMarkerElement.h" -#include "Attribute.h" #include "RenderSVGResourceMarker.h" -#include "SVGElementInstance.h" #include "SVGFitToViewBox.h" #include "SVGNames.h" -#include "SVGSVGElement.h" +#include <wtf/NeverDestroyed.h> namespace WebCore { @@ -87,20 +83,20 @@ inline SVGMarkerElement::SVGMarkerElement(const QualifiedName& tagName, Document registerAnimatedPropertiesForSVGMarkerElement(); } -PassRefPtr<SVGMarkerElement> SVGMarkerElement::create(const QualifiedName& tagName, Document& document) +Ref<SVGMarkerElement> SVGMarkerElement::create(const QualifiedName& tagName, Document& document) { - return adoptRef(new SVGMarkerElement(tagName, document)); + return adoptRef(*new SVGMarkerElement(tagName, document)); } const AtomicString& SVGMarkerElement::orientTypeIdentifier() { - DEFINE_STATIC_LOCAL(AtomicString, s_identifier, ("SVGOrientType", AtomicString::ConstructFromLiteral)); + static NeverDestroyed<AtomicString> s_identifier("SVGOrientType", AtomicString::ConstructFromLiteral); return s_identifier; } const AtomicString& SVGMarkerElement::orientAngleIdentifier() { - DEFINE_STATIC_LOCAL(AtomicString, s_identifier, ("SVGOrientAngle", AtomicString::ConstructFromLiteral)); + static NeverDestroyed<AtomicString> s_identifier("SVGOrientAngle", AtomicString::ConstructFromLiteral); return s_identifier; } @@ -111,53 +107,56 @@ AffineTransform SVGMarkerElement::viewBoxToViewTransform(float viewWidth, float bool SVGMarkerElement::isSupportedAttribute(const QualifiedName& attrName) { - DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ()); - if (supportedAttributes.isEmpty()) { + static NeverDestroyed<HashSet<QualifiedName>> supportedAttributes; + if (supportedAttributes.get().isEmpty()) { SVGLangSpace::addSupportedAttributes(supportedAttributes); SVGExternalResourcesRequired::addSupportedAttributes(supportedAttributes); SVGFitToViewBox::addSupportedAttributes(supportedAttributes); - supportedAttributes.add(SVGNames::markerUnitsAttr); - supportedAttributes.add(SVGNames::refXAttr); - supportedAttributes.add(SVGNames::refYAttr); - supportedAttributes.add(SVGNames::markerWidthAttr); - supportedAttributes.add(SVGNames::markerHeightAttr); - supportedAttributes.add(SVGNames::orientAttr); + supportedAttributes.get().add(SVGNames::markerUnitsAttr); + supportedAttributes.get().add(SVGNames::refXAttr); + supportedAttributes.get().add(SVGNames::refYAttr); + supportedAttributes.get().add(SVGNames::markerWidthAttr); + supportedAttributes.get().add(SVGNames::markerHeightAttr); + supportedAttributes.get().add(SVGNames::orientAttr); } - return supportedAttributes.contains<SVGAttributeHashTranslator>(attrName); + return supportedAttributes.get().contains<SVGAttributeHashTranslator>(attrName); } void SVGMarkerElement::parseAttribute(const QualifiedName& name, const AtomicString& value) { - SVGParsingError parseError = NoError; - - if (!isSupportedAttribute(name)) - SVGElement::parseAttribute(name, value); - else if (name == SVGNames::markerUnitsAttr) { - SVGMarkerUnitsType propertyValue = SVGPropertyTraits<SVGMarkerUnitsType>::fromString(value); + if (name == SVGNames::markerUnitsAttr) { + auto propertyValue = SVGPropertyTraits<SVGMarkerUnitsType>::fromString(value); if (propertyValue > 0) setMarkerUnitsBaseValue(propertyValue); - } else if (name == SVGNames::refXAttr) - setRefXBaseValue(SVGLength::construct(LengthModeWidth, value, parseError)); - else if (name == SVGNames::refYAttr) - setRefYBaseValue(SVGLength::construct(LengthModeHeight, value, parseError)); - else if (name == SVGNames::markerWidthAttr) - setMarkerWidthBaseValue(SVGLength::construct(LengthModeWidth, value, parseError)); - else if (name == SVGNames::markerHeightAttr) - setMarkerHeightBaseValue(SVGLength::construct(LengthModeHeight, value, parseError)); - else if (name == SVGNames::orientAttr) { - SVGAngle angle; - SVGMarkerOrientType orientType = SVGPropertyTraits<SVGMarkerOrientType>::fromString(value, angle); + return; + } + + if (name == SVGNames::orientAttr) { + SVGAngleValue angle; + auto orientType = SVGPropertyTraits<SVGMarkerOrientType>::fromString(value, angle); if (orientType > 0) setOrientTypeBaseValue(orientType); if (orientType == SVGMarkerOrientAngle) setOrientAngleBaseValue(angle); - } else if (SVGLangSpace::parseAttribute(name, value) - || SVGExternalResourcesRequired::parseAttribute(name, value) - || SVGFitToViewBox::parseAttribute(this, name, value)) { - } else - ASSERT_NOT_REACHED(); + return; + } + + SVGParsingError parseError = NoError; + + if (name == SVGNames::refXAttr) + setRefXBaseValue(SVGLengthValue::construct(LengthModeWidth, value, parseError)); + else if (name == SVGNames::refYAttr) + setRefYBaseValue(SVGLengthValue::construct(LengthModeHeight, value, parseError)); + else if (name == SVGNames::markerWidthAttr) + setMarkerWidthBaseValue(SVGLengthValue::construct(LengthModeWidth, value, parseError)); + else if (name == SVGNames::markerHeightAttr) + setMarkerHeightBaseValue(SVGLengthValue::construct(LengthModeHeight, value, parseError)); reportAttributeParsingError(parseError, name, value); + + SVGElement::parseAttribute(name, value); + SVGExternalResourcesRequired::parseAttribute(name, value); + SVGFitToViewBox::parseAttribute(this, name, value); } void SVGMarkerElement::svgAttributeChanged(const QualifiedName& attrName) @@ -167,7 +166,7 @@ void SVGMarkerElement::svgAttributeChanged(const QualifiedName& attrName) return; } - SVGElementInstance::InvalidationGuard invalidationGuard(this); + InstanceInvalidationGuard guard(*this); if (attrName == SVGNames::refXAttr || attrName == SVGNames::refYAttr @@ -190,11 +189,11 @@ void SVGMarkerElement::childrenChanged(const ChildChange& change) object->setNeedsLayout(); } -void SVGMarkerElement::setOrientToAuto() +void SVGMarkerElement::setOrient(SVGMarkerOrientType orientType, const SVGAngleValue& angle) { - setOrientTypeBaseValue(SVGMarkerOrientAuto); - setOrientAngleBaseValue(SVGAngle()); - + setOrientTypeBaseValue(orientType); + setOrientAngleBaseValue(angle); + // Mark orientAttr dirty - the next XML DOM access of that attribute kicks in synchronization. m_orientAngle.shouldSynchronize = true; m_orientType.shouldSynchronize = true; @@ -202,21 +201,19 @@ void SVGMarkerElement::setOrientToAuto() svgAttributeChanged(orientAnglePropertyInfo()->attributeName); } -void SVGMarkerElement::setOrientToAngle(const SVGAngle& angle) +void SVGMarkerElement::setOrientToAuto() { - setOrientTypeBaseValue(SVGMarkerOrientAngle); - setOrientAngleBaseValue(angle); + setOrient(SVGMarkerOrientAuto, { }); +} - // Mark orientAttr dirty - the next XML DOM access of that attribute kicks in synchronization. - m_orientAngle.shouldSynchronize = true; - m_orientType.shouldSynchronize = true; - invalidateSVGAttributes(); - svgAttributeChanged(orientAnglePropertyInfo()->attributeName); +void SVGMarkerElement::setOrientToAngle(SVGAngle& angle) +{ + setOrient(SVGMarkerOrientAngle, angle.propertyReference()); } -RenderPtr<RenderElement> SVGMarkerElement::createElementRenderer(PassRef<RenderStyle> style) +RenderPtr<RenderElement> SVGMarkerElement::createElementRenderer(RenderStyle&& style, const RenderTreePosition&) { - return createRenderer<RenderSVGResourceMarker>(*this, std::move(style)); + return createRenderer<RenderSVGResourceMarker>(*this, WTFMove(style)); } bool SVGMarkerElement::selfHasRelativeLengths() const @@ -230,32 +227,46 @@ bool SVGMarkerElement::selfHasRelativeLengths() const void SVGMarkerElement::synchronizeOrientType(SVGElement* contextElement) { ASSERT(contextElement); - SVGMarkerElement* ownerType = toSVGMarkerElement(contextElement); - if (!ownerType->m_orientType.shouldSynchronize) + SVGMarkerElement& ownerType = downcast<SVGMarkerElement>(*contextElement); + if (!ownerType.m_orientType.shouldSynchronize) return; - // If orient is not auto, the previous call to synchronizeOrientAngle already set the orientAttr to the right angle. - if (ownerType->m_orientType.value != SVGMarkerOrientAuto) + static NeverDestroyed<AtomicString> autoString("auto", AtomicString::ConstructFromLiteral); + static NeverDestroyed<AtomicString> autoStartReverseString("auto-start-reverse", AtomicString::ConstructFromLiteral); + + // If orient is not auto or auto-start-reverse, the previous call to synchronizeOrientAngle already set the orientAttr to the right angle. + if (ownerType.m_orientType.value == SVGMarkerOrientAuto) { + ownerType.m_orientType.synchronize(&ownerType, orientTypePropertyInfo()->attributeName, autoString); return; + } - DEFINE_STATIC_LOCAL(AtomicString, autoString, ("auto", AtomicString::ConstructFromLiteral)); - ownerType->m_orientType.synchronize(ownerType, orientTypePropertyInfo()->attributeName, autoString); + if (ownerType.m_orientType.value == SVGMarkerOrientAutoStartReverse) + ownerType.m_orientType.synchronize(&ownerType, orientTypePropertyInfo()->attributeName, autoStartReverseString); } -PassRefPtr<SVGAnimatedProperty> SVGMarkerElement::lookupOrCreateOrientTypeWrapper(SVGElement* contextElement) +Ref<SVGAnimatedProperty> SVGMarkerElement::lookupOrCreateOrientTypeWrapper(SVGElement* contextElement) { ASSERT(contextElement); - SVGMarkerElement* ownerType = toSVGMarkerElement(contextElement); + SVGMarkerElement& ownerType = downcast<SVGMarkerElement>(*contextElement); return SVGAnimatedProperty::lookupOrCreateWrapper<SVGMarkerElement, SVGAnimatedEnumerationPropertyTearOff<SVGMarkerOrientType>, SVGMarkerOrientType> - (ownerType, orientTypePropertyInfo(), ownerType->m_orientType.value); + (&ownerType, orientTypePropertyInfo(), ownerType.m_orientType.value); } - -PassRefPtr<SVGAnimatedEnumerationPropertyTearOff<SVGMarkerOrientType>> SVGMarkerElement::orientTypeAnimated() + +SVGMarkerOrientType& SVGMarkerElement::orientType() const { - m_orientType.shouldSynchronize = true; - return static_pointer_cast<SVGAnimatedEnumerationPropertyTearOff<SVGMarkerOrientType>>(lookupOrCreateOrientTypeWrapper(this)); + if (auto wrapper = SVGAnimatedProperty::lookupWrapper<UseOwnerType, SVGAnimatedEnumeration>(this, orientTypePropertyInfo())) { + if (wrapper->isAnimating()) { + ASSERT(wrapper->currentAnimatedValue() < SVGMarkerOrientMax); + return reinterpret_cast<SVGMarkerOrientType&>(wrapper->currentAnimatedValue()); + } + } + return m_orientType.value; } +Ref<SVGAnimatedEnumerationPropertyTearOff<SVGMarkerOrientType>> SVGMarkerElement::orientTypeAnimated() +{ + m_orientType.shouldSynchronize = true; + return static_reference_cast<SVGAnimatedEnumerationPropertyTearOff<SVGMarkerOrientType>>(lookupOrCreateOrientTypeWrapper(this)); } -#endif +} |