diff options
Diffstat (limited to 'Source/WebCore/svg/SVGTextContentElement.cpp')
-rw-r--r-- | Source/WebCore/svg/SVGTextContentElement.cpp | 165 |
1 files changed, 69 insertions, 96 deletions
diff --git a/Source/WebCore/svg/SVGTextContentElement.cpp b/Source/WebCore/svg/SVGTextContentElement.cpp index ef9920eff..12f1dcbf3 100644 --- a/Source/WebCore/svg/SVGTextContentElement.cpp +++ b/Source/WebCore/svg/SVGTextContentElement.cpp @@ -19,8 +19,6 @@ */ #include "config.h" - -#if ENABLE(SVG) #include "SVGTextContentElement.h" #include "CSSPropertyNames.h" @@ -31,17 +29,19 @@ #include "RenderSVGResource.h" #include "RenderSVGText.h" #include "SVGDocumentExtensions.h" -#include "SVGElementInstance.h" #include "SVGNames.h" +#include "SVGPoint.h" +#include "SVGRect.h" #include "SVGTextQuery.h" #include "XMLNames.h" +#include <wtf/NeverDestroyed.h> namespace WebCore { // Define custom animated property 'textLength'. const SVGPropertyInfo* SVGTextContentElement::textLengthPropertyInfo() { - static const SVGPropertyInfo* s_propertyInfo = 0; + static const SVGPropertyInfo* s_propertyInfo = nullptr; if (!s_propertyInfo) { s_propertyInfo = new SVGPropertyInfo(AnimatedLength, PropertyIsReadWrite, @@ -76,30 +76,29 @@ SVGTextContentElement::SVGTextContentElement(const QualifiedName& tagName, Docum void SVGTextContentElement::synchronizeTextLength(SVGElement* contextElement) { ASSERT(contextElement); - SVGTextContentElement* ownerType = toSVGTextContentElement(contextElement); - if (!ownerType->m_textLength.shouldSynchronize) + SVGTextContentElement& ownerType = downcast<SVGTextContentElement>(*contextElement); + if (!ownerType.m_textLength.shouldSynchronize) return; - AtomicString value(SVGPropertyTraits<SVGLength>::toString(ownerType->m_specifiedTextLength)); - ownerType->m_textLength.synchronize(ownerType, textLengthPropertyInfo()->attributeName, value); + AtomicString value(SVGPropertyTraits<SVGLengthValue>::toString(ownerType.m_specifiedTextLength)); + ownerType.m_textLength.synchronize(&ownerType, textLengthPropertyInfo()->attributeName, value); } -PassRefPtr<SVGAnimatedProperty> SVGTextContentElement::lookupOrCreateTextLengthWrapper(SVGElement* contextElement) +Ref<SVGAnimatedProperty> SVGTextContentElement::lookupOrCreateTextLengthWrapper(SVGElement* contextElement) { ASSERT(contextElement); - SVGTextContentElement* ownerType = toSVGTextContentElement(contextElement); - return SVGAnimatedProperty::lookupOrCreateWrapper<SVGTextContentElement, SVGAnimatedLength, SVGLength> - (ownerType, textLengthPropertyInfo(), ownerType->m_textLength.value); + SVGTextContentElement& ownerType = downcast<SVGTextContentElement>(*contextElement); + return SVGAnimatedProperty::lookupOrCreateWrapper<SVGTextContentElement, SVGAnimatedLength, SVGLengthValue> + (&ownerType, textLengthPropertyInfo(), ownerType.m_textLength.value); } -PassRefPtr<SVGAnimatedLength> SVGTextContentElement::textLengthAnimated() +Ref<SVGAnimatedLength> SVGTextContentElement::textLengthAnimated() { - DEFINE_STATIC_LOCAL(SVGLength, defaultTextLength, (LengthModeOther)); + static NeverDestroyed<SVGLengthValue> defaultTextLength(LengthModeOther); if (m_specifiedTextLength == defaultTextLength) - m_textLength.value.newValueSpecifiedUnits(LengthTypeNumber, getComputedTextLength(), ASSERT_NO_EXCEPTION); + m_textLength.value.newValueSpecifiedUnits(LengthTypeNumber, getComputedTextLength()); m_textLength.shouldSynchronize = true; - return static_pointer_cast<SVGAnimatedLength>(lookupOrCreateTextLengthWrapper(this)); - + return static_reference_cast<SVGAnimatedLength>(lookupOrCreateTextLengthWrapper(this)); } unsigned SVGTextContentElement::getNumberOfChars() @@ -114,83 +113,61 @@ float SVGTextContentElement::getComputedTextLength() return SVGTextQuery(renderer()).textLength(); } -float SVGTextContentElement::getSubStringLength(unsigned charnum, unsigned nchars, ExceptionCode& ec) +ExceptionOr<float> SVGTextContentElement::getSubStringLength(unsigned charnum, unsigned nchars) { - document().updateLayoutIgnorePendingStylesheets(); - unsigned numberOfChars = getNumberOfChars(); - if (charnum >= numberOfChars) { - ec = INDEX_SIZE_ERR; - return 0.0f; - } + if (charnum >= numberOfChars) + return Exception { INDEX_SIZE_ERR }; + nchars = std::min(nchars, numberOfChars - charnum); return SVGTextQuery(renderer()).subStringLength(charnum, nchars); } -SVGPoint SVGTextContentElement::getStartPositionOfChar(unsigned charnum, ExceptionCode& ec) +ExceptionOr<Ref<SVGPoint>> SVGTextContentElement::getStartPositionOfChar(unsigned charnum) { - document().updateLayoutIgnorePendingStylesheets(); - - if (charnum > getNumberOfChars()) { - ec = INDEX_SIZE_ERR; - return SVGPoint(); - } + if (charnum > getNumberOfChars()) + return Exception { INDEX_SIZE_ERR }; - return SVGTextQuery(renderer()).startPositionOfCharacter(charnum); + return SVGPoint::create(SVGTextQuery(renderer()).startPositionOfCharacter(charnum)); } -SVGPoint SVGTextContentElement::getEndPositionOfChar(unsigned charnum, ExceptionCode& ec) +ExceptionOr<Ref<SVGPoint>> SVGTextContentElement::getEndPositionOfChar(unsigned charnum) { - document().updateLayoutIgnorePendingStylesheets(); - - if (charnum > getNumberOfChars()) { - ec = INDEX_SIZE_ERR; - return SVGPoint(); - } + if (charnum > getNumberOfChars()) + return Exception { INDEX_SIZE_ERR }; - return SVGTextQuery(renderer()).endPositionOfCharacter(charnum); + return SVGPoint::create(SVGTextQuery(renderer()).endPositionOfCharacter(charnum)); } -FloatRect SVGTextContentElement::getExtentOfChar(unsigned charnum, ExceptionCode& ec) +ExceptionOr<Ref<SVGRect>> SVGTextContentElement::getExtentOfChar(unsigned charnum) { - document().updateLayoutIgnorePendingStylesheets(); - - if (charnum > getNumberOfChars()) { - ec = INDEX_SIZE_ERR; - return FloatRect(); - } + if (charnum > getNumberOfChars()) + return Exception { INDEX_SIZE_ERR }; - return SVGTextQuery(renderer()).extentOfCharacter(charnum); + return SVGRect::create(SVGTextQuery(renderer()).extentOfCharacter(charnum)); } -float SVGTextContentElement::getRotationOfChar(unsigned charnum, ExceptionCode& ec) +ExceptionOr<float> SVGTextContentElement::getRotationOfChar(unsigned charnum) { - document().updateLayoutIgnorePendingStylesheets(); - - if (charnum > getNumberOfChars()) { - ec = INDEX_SIZE_ERR; - return 0.0f; - } + if (charnum > getNumberOfChars()) + return Exception { INDEX_SIZE_ERR }; return SVGTextQuery(renderer()).rotationOfCharacter(charnum); } -int SVGTextContentElement::getCharNumAtPosition(const SVGPoint& point) +int SVGTextContentElement::getCharNumAtPosition(SVGPoint& point) { document().updateLayoutIgnorePendingStylesheets(); - return SVGTextQuery(renderer()).characterNumberAtPosition(point); + return SVGTextQuery(renderer()).characterNumberAtPosition(point.propertyReference()); } -void SVGTextContentElement::selectSubString(unsigned charnum, unsigned nchars, ExceptionCode& ec) +ExceptionOr<void> SVGTextContentElement::selectSubString(unsigned charnum, unsigned nchars) { unsigned numberOfChars = getNumberOfChars(); - if (charnum >= numberOfChars) { - ec = INDEX_SIZE_ERR; - return; - } + if (charnum >= numberOfChars) + return Exception { INDEX_SIZE_ERR }; - if (nchars > numberOfChars - charnum) - nchars = numberOfChars - charnum; + nchars = std::min(nchars, numberOfChars - charnum); ASSERT(document().frame()); @@ -207,18 +184,20 @@ void SVGTextContentElement::selectSubString(unsigned charnum, unsigned nchars, E end = end.next(); selection.setSelection(VisibleSelection(start, end)); + + return { }; } bool SVGTextContentElement::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); - supportedAttributes.add(SVGNames::lengthAdjustAttr); - supportedAttributes.add(SVGNames::textLengthAttr); + supportedAttributes.get().add(SVGNames::lengthAdjustAttr); + supportedAttributes.get().add(SVGNames::textLengthAttr); } - return supportedAttributes.contains<SVGAttributeHashTranslator>(attrName); + return supportedAttributes.get().contains<SVGAttributeHashTranslator>(attrName); } bool SVGTextContentElement::isPresentationAttribute(const QualifiedName& name) const @@ -230,36 +209,32 @@ bool SVGTextContentElement::isPresentationAttribute(const QualifiedName& name) c void SVGTextContentElement::collectStyleForPresentationAttribute(const QualifiedName& name, const AtomicString& value, MutableStyleProperties& style) { - if (!isSupportedAttribute(name)) - SVGGraphicsElement::collectStyleForPresentationAttribute(name, value, style); - else if (name.matches(XMLNames::spaceAttr)) { - DEFINE_STATIC_LOCAL(const AtomicString, preserveString, ("preserve", AtomicString::ConstructFromLiteral)); - - if (value == preserveString) + if (name.matches(XMLNames::spaceAttr)) { + if (value == "preserve") addPropertyToPresentationAttributeStyle(style, CSSPropertyWhiteSpace, CSSValuePre); else addPropertyToPresentationAttributeStyle(style, CSSPropertyWhiteSpace, CSSValueNowrap); + return; } + + SVGGraphicsElement::collectStyleForPresentationAttribute(name, value, style); } void SVGTextContentElement::parseAttribute(const QualifiedName& name, const AtomicString& value) { SVGParsingError parseError = NoError; - if (!isSupportedAttribute(name)) - SVGGraphicsElement::parseAttribute(name, value); - else if (name == SVGNames::lengthAdjustAttr) { - SVGLengthAdjustType propertyValue = SVGPropertyTraits<SVGLengthAdjustType>::fromString(value); + if (name == SVGNames::lengthAdjustAttr) { + auto propertyValue = SVGPropertyTraits<SVGLengthAdjustType>::fromString(value); if (propertyValue > 0) setLengthAdjustBaseValue(propertyValue); - } else if (name == SVGNames::textLengthAttr) { - m_textLength.value = SVGLength::construct(LengthModeOther, value, parseError, ForbidNegativeLengths); - } else if (SVGExternalResourcesRequired::parseAttribute(name, value)) { - } else if (SVGLangSpace::parseAttribute(name, value)) { - } else - ASSERT_NOT_REACHED(); + } else if (name == SVGNames::textLengthAttr) + m_textLength.value = SVGLengthValue::construct(LengthModeOther, value, parseError, ForbidNegativeLengths); reportAttributeParsingError(parseError, name, value); + + SVGGraphicsElement::parseAttribute(name, value); + SVGExternalResourcesRequired::parseAttribute(name, value); } void SVGTextContentElement::svgAttributeChanged(const QualifiedName& attrName) @@ -269,13 +244,13 @@ void SVGTextContentElement::svgAttributeChanged(const QualifiedName& attrName) return; } - SVGElementInstance::InvalidationGuard invalidationGuard(this); - if (attrName == SVGNames::textLengthAttr) m_specifiedTextLength = m_textLength.value; - if (auto renderer = this->renderer()) + if (auto renderer = this->renderer()) { + InstanceInvalidationGuard guard(*this); RenderSVGResource::markForLayoutAndParentResourceInvalidation(*renderer); + } } bool SVGTextContentElement::selfHasRelativeLengths() const @@ -289,20 +264,18 @@ bool SVGTextContentElement::selfHasRelativeLengths() const SVGTextContentElement* SVGTextContentElement::elementFromRenderer(RenderObject* renderer) { if (!renderer) - return 0; + return nullptr; if (!renderer->isSVGText() && !renderer->isSVGInline()) - return 0; + return nullptr; - SVGElement* element = toSVGElement(renderer->node()); + SVGElement* element = downcast<SVGElement>(renderer->node()); ASSERT(element); - if (!element->isTextContent()) - return 0; + if (!is<SVGTextContentElement>(*element)) + return nullptr; - return toSVGTextContentElement(element); + return downcast<SVGTextContentElement>(element); } } - -#endif // ENABLE(SVG) |