# Re: normalizedPathSegList in SVGPathElement

From: Dirk Schulze <vbs85@gmx.de>
Date: Sun, 05 Sep 2010 18:30:57 +0200
To: "Dr. Olaf Hoffmann" <Dr.O.Hoffmann@gmx.de>

Message-ID: <1283704257.28494.196.camel@dirk-laptop>
```
> Conversion from relative paths to absolute paths  and S to C and T to Q
> and H, V to L as mentioned in SVG tiny 1.2 should be trivial.

Indeed, the normalization of simple segments like m,l,c,Q,q,T,t,h,H,v,V
is not difficult.

> If elliptical arcs are approximated with cubic curves, one
> always has to do the approximation for each animation
> interpolation step. And because it is an approximation,
> to provide a simple rule to get the cubic curves path segments
> representing an elliptical arc within the requirement of SVG to
> have at least an accuracy of one device pixel might be not trivial.
> For this to hear some ideas how to get it correct enough
> and fast (with a minimal number of cubic curves to meet
> the required precision) at the same time would be interesting :o)

For arc we take the center parameterization and split the arc to cubic
curves every 45 degree (at least if I remember correctly). And yes, we
do it for every single interpolation step on animations at the moment.
It could be more efficient to use the flattened path directly, but this
depends on the maths that would be needed to do so.

Nevertheless, I think the complicated part here is the synchronization.
Short example (complete example on the bottom of this mail):

We have a path: d="M 10 50 A 40 40 180 1 0 90 50 l 0 -40 z" (MAlz).

We take a reference to the arc segment:
var arcAbsSegment = path.pathSegList.getItem(1);

Now we take the normalizedPathSegList (MCCLZ on Opera) and modify the
lineToAbs:
path.normalizedPathSegList.getItem(3).y = 50;

The pathSegList gets synchronized with the normalPathSegList now.
There are two ways to do so:
We could either completely replace the pathSegList with the
normalizedPathSegList, or just replace the relative lineTo with the
absolute lineTo from the normalizedPathSegList.
The specification recommends to use the second one, but I think both
ways are possible.[1]

Lets choose the second synchronization like Opera does. This would mean,
that 'arcAbsSegment' is still part of the pathSegList and every
modification to this segment effects the pathSegList. This isn't the
case for the complete replacement.
Recording every mapping to have a bijective link between the segments on
both lists can be a big performance issue, mainly if we have multiple
modifications on both lists. An unnecessary waste, if browsers differ on
the synchronization.

I would prefer the complete replacement, since it's easier to do, takes
less memory, is maybe faster and much easier to specify. But of course
replacing the relevant parts is more elegant.

Dirk

[1] http://www.w3.org/TR/SVG/paths.html#InterfaceSVGAnimatedPathData

complete example:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<script type="text/javascript">
<![CDATA[
/*
http://www.w3.org/TR/SVG/paths.html#__svg__SVGAnimatedPathData__normalizedPathSegList */
function checkPathSeg() {
var path = document.getElementById("path");
// Take the arc for later changes.
var arcAbsSegment = path.pathSegList.getItem(1);

// normalizedPathSegList on Opera 10.60: MCCLZ
// lineRel got to lineAbs. Take lineAbs.
var lineAbsSegment = path.normalizedPathSegList.getItem(3);
lineAbsSegment.y = 50;

// Modify arcAbsSegment from the old pathSegList now.
// Should it effect the current pathSegList?
arcAbsSegment.r2 = 10;
}
]]>
</script>