Changes between Version 11 and Version 12 of SVG properties


Ignore:
Timestamp:
Mar 10, 2019 7:20:40 PM (2 years ago)
Author:
Said Abou-Hallawa
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • SVG properties

    v11 v12  
    12123. It is a reflection of a DOM attribute. Two cases have to be handled:
    1313 a. When setAttribute() called for the underlaying attribute, SVGElement::parseAttribute() will be called to update the SVG property. Then SVGElement::svgAttributeChanged() is called to invalidate the renderer and the dependent SVG objects.
    14  b. When the SVG property is changed through the DOM interface. In this handled in two steps:
     14 b. When the SVG property is changed through the DOM interface. This change will be handled in two steps:
    1515  * The commit step which is called immediately after changing the property's value. It will mark the value of the underlaying attribute to be invalid and it will call  SVGElement::svgAttributeChanged().
    16   *  The synchronize step which happens later when the value of attribute is required. The valueAsString() of the SVG property is set as the attribute value.
     16  *  The synchronize step which happens later when the value of attribute is required. The valueAsString() of the SVG property is set as the attribute value. In other words, synchronizing the attribute value is lazily updated from the reflection SVG property only when it is needed.
    17174. Most of the properties are animated properties. The animated property has two members baseVal() and the animal(). Each of them are from the same SVG property type.  animal() differs from baseVal() only when animating. Otherwise they have to be the same value.
    18185. The animal() of the animated property is read only; no changes from the DOM is allowed.
     
    2020 * When the property is attached, a change in its value has to be synchronized with the attribute value.
    2121 * When the property is detached, a change in its value has no effect on any other element.
    22 7. Some properties are SVG lists of SVG types, e.g. SVGNumberList and SVGPointList. In addition of having the list itself Refcounted, all the items of this list have to be RefCounted also. The items can outlive the owner list.
     227. Some properties are SVG lists of SVG types, e.g. SVGNumberList and SVGPointList. In addition of having the list itself Refcounted, all the items of this list have to be RefCounted also. The items can outlive the owner list and the owner list.
    2323
    2424**SVG Tear-Off objects**
    2525
    26 The old design of managing the SVG properties relied on storing only the underlaying data in the SVG element. For example, the SVGRectElement was storing an SVGLengthValue for the baseVal of 'x' property. When the property is requested from the DOM a SVGAnimatedLength has to be constructed. Constructing the SVGAnimatedLength happens through creating and caching an animated SVG tear-off object. The animated tear-off object is a RefCounted and it holds two SVGLength objects for the baseVal and the animVal. The SVGLength object is another type of tear-off objects. This design has many flaws:
     26The old design of managing the SVG properties relied on storing only the underlaying data in the SVG element. For example, the SVGRectElement was storing an an SVGLengthValue for the baseVal of 'x' property. When the property is requested from the DOM an SVGAnimatedLength has to be constructed. Constructing the SVGAnimatedLength happens through creating and caching an animated SVG tear-off object. The animated tear-off object is a RefCounted and it holds two SVGLength objects for the baseVal and the animVal. The SVGLength object is another type of tear-off objects. This design has many flaws:
    27271. The animated tear off objects are cached in a hash table outside of the SVGElement although it holds a raw pointer to the property raw data in the SVGElement.
    28282. It was difficult to deal with optional properties, for example the 'stdDeviation' property of SVGFEGaussianBlurElement. This is because the key of hash table is the pair <SVGElement, attributeName>
    29293. It was difficult to deal with list properties, for example the 'x' property of SVGTextPositioningElement. The individual items of the SVG tear off object holds raw pointers to the raw data items in the SVGElement. It becomes even more difficult when animating. The animVal tear off list owns the values of the items while the baseVal tear off list items hold pointers to the raw data which is held by the SVGElement.
     304. When animating, SVGAnimateElementBase creates SVGAnimatedType objects for from, to, toAtEndOfDuration and current values. The SVGAnimatedType is basically a union of raw pointers to the raw data. The current SVGAnimatedType points to the raw data stored by the animVal of the SVG tear off objects. The rest of the SVGAnimatedType objects points to raw data created by the SVGAnimator when parsing the from, to and toAtEndOfDuration strings.
    3031
    3132**New Design for the SVG properties**
    3233
    3334The goal of the new design is to make the life cycle of the SVG properties clear. It has to well define the relationship between the property and its owner such that synchronizing the change in the property with the SVGElement becomes straightforward.
    34 * The SVGElement will own the RefCounted animated SVG property with will own the RefCounted SVG properties for the baseVal and the animVal. This eliminate the need to cache animated SVG property outside the SVGElement like what the SVG tear off objects were doing.
     35* The SVGElement will own the RefCounted animated SVG property which will own the RefCounted SVG properties for the baseVal and the animVal. This eliminates the need to cache the animated SVG property outside the SVGElement like what the SVG tear off objects were doing.
    3536* If the property is of list of an SVG type, the items will be RefCounted of the SVG type.
    3637* The properties will be registered once by the owner SVGElement to associate a pointer to a member in the SVGElement with an attributeName.
    37 * The property registry will create an accessor for every property. The accessor knows how to get the property value when it is given an SVGElement.
    38 * The SMIL animation is carried out by an SVGAnimator. The SVGAnimator calculates the new value of the animVal by the SVGAnimationFunction. The SVGAnimator commits the change in the animVal by invalidating the SVGElement. The SVG renderer will get the new animVal when it gets the property value and the SVGElement finds that the property is being animated.
     38* The property registry will create an accessor for every property. The accessor knows how to get the property value when it is given a pointer to an SVGElement.
     39* The SMIL animation is carried out by new types of SVGAnimator. The SVGAnimator calculates the new value of the animVal by the SVGAnimationFunction. The SVGAnimator commits the change in the animVal by invalidating the SVGElement. The SVG renderer will get the new animVal when it gets the property value and the SVGElement finds that the property is being animated.
    3940
    4041**Mechanic of the SVG property**
     
    5253Ref<SVGAnimatedLength> m_x { SVGAnimatedLength::create(this, LengthModeWidth) };
    5354}}}
    54 4. The SVGAnimatedLength has two members named m_baseVal and m_animVal. Both of them are of type SVGLength.
    55 5. The property is registered only once in the constructor of the SVG element. This registration will associate the data member with the attribute name. For example the constructor of the SVGRectElement will have this statement:
     554. Define the following two functions for every property with the same name. The first is one a const function. This function will return the current value. The expectation is this function will be called from the rendering code. So it does not have to get a RefCounted to the animated property. But rather it cares about the current value only. The second one is none const function. The expectation is this function will be called from the DOM interface. So it needs the RefCounted animated property. For example the SVGRectElement will have these two methods for the 'x' property:
     56{{{
     57const SVGLengthValue& x() const { return m_x->currentValue(); }
     58Ref<SVGAnimatedLength>& x() { return m_x; }
     59}}}
     605. The SVGAnimatedLength has two members named m_baseVal and m_animVal. Both of them are of type SVGLength.
     616. The property is registered only once in the constructor of the SVG element. This registration will associate the data member with the attribute name. For example the constructor of the SVGRectElement will have this statement:
    5662{{{
    5763PropertyRegistry::registerProperty<SVGNames::xAttr, &SVGRectElement::m_x>();
    5864}}}
    59 6. This statement calls the override method of SVGPropertyOwnerRegistry
     657. This statement calls the override method of SVGPropertyOwnerRegistry
    6066{{{
    6167template<const LazyNeverDestroyed<const QualifiedName>& attributeName, Ref<SVGAnimatedLength> OwnerType::*property>
     
    6571}
    6672}}}
    67 7. This registration associates a pointer to a member of SVGRectElement with the attributeName through the SVGAnimatedLengthAccessor.
    68 8. When the animation of an SVG animated property starts, SVGAnimateElementBase asks the SVGPropertyRegistry to create an SVGAnimator for this property. SVGPropertyRegistry finds the property accessor and asks it to create the SVGAnimator. For example, this is the createAnimator method of SVGAnimatedLengthAccessor:
     738. This registration associates a pointer to a member of SVGRectElement with the attributeName through the SVGAnimatedLengthAccessor.
     749. When the animation of an SVG animated property starts, SVGAnimateElementBase asks the SVGPropertyRegistry to create an SVGAnimator for this property. SVGPropertyRegistry finds the property accessor and asks it to create the SVGAnimator. For example, this is the createAnimator method of SVGAnimatedLengthAccessor:
    6975{{{
    7076RefPtr<SVGAnimator> createAnimator(OwnerType& owner, const QualifiedName& attributeName, AnimationMode animationMode, CalcMode calcMode, bool isAccumulated, bool isAdditive) const final
     
    7480}
    7581}}}
    76 9. When SVGAnimateElementBase wants to progress the animation, it asks the animator to calculate a new value of the property based on the timeline of the animation. The SVGAnimator asks the SVGAnimationFunction to do so given a reference to  the animVal of the property. For example here is the progress() method of SVGAnimatedLengthAnimator:
     8210. When SVGAnimateElementBase wants to progress the animation, it asks the animator to calculate a new value of the property based on the timeline of the animation. The SVGAnimator asks the SVGAnimationFunction to do so given a reference to  the animVal of the property. For example here is the progress() method of SVGAnimatedLengthAnimator:
    7783{{{
    78 \void progress(SVGElement* targetElement, float percentage, unsigned repeatCount) final
     84void progress(SVGElement* targetElement, float percentage, unsigned repeatCount) final
    7985{
    8086    m_function.progress(targetElement, percentage, repeatCount, m_animated->animVal()->value());