SVG 2 – 09 April 2013 TopContentsPreviousNextElementsAttributesProperties

Chapter 11: Painting: Filling, Stroking and Marker Symbols

Contents

11.1. Introduction

Graphical elements that define a shape – path elements, basic shapes and text content elements – are rendered by being filled, which is painting the interior of the object, and stroked, which is painting along the outline of the object. Filling and stroking are both painting operations. SVG 2 supports a number of different paints that the fill and stroke of a graphical element can be painted with:

The paint to use for filling and stroking an element is specified using the ‘fill’ and ‘stroke’ properties. The following section describes the different values that can be used for these properties.

Other properties, such as ‘fill-opacity’ and ‘stroke-width’, also have an effect on the way fill and stroke paint is applied to the canvas. The Fill properties and Stroke properties sections below describe these properties.

Certain elements – path, polyline, polygon and line elements – can also have marker symbols drawn at their vertices or at other positions along the path that they describe. The Markers section below describes how markers can be defined and used.

11.2. Specifying paint

SVG 2 Requirement: Add new paint values for referencing current fill paint, stroke paint, etc.
Resolution: We will add new paint values currentFillPaint, currentStrokePaint etc. to SVG 2
Purpose: Among other things, to provide an easy way to match marker color to stroke color.
Owner: Chris (ACTION-3094)

Properties ‘fill’ and ‘stroke’ take on a value of type <paint>:

<paint> =
none |
<color> |
[ <color>? <icccolor> ] |
<gradient> |
[ [ <funciri> | child | <child-selector> ] [ none | <color> | [ <color>? <icccolor> ] ]? ] |
context-fill |
context-stroke

Values have the following meaning:

none
Indicates that no paint is applied.
<color>
A solid color as defined in CSS Color Module Level 3. [CSS3COLOR] All forms of <color> defined by that specification are valid for use as a <paint> value. This includes the basic color keywords, RGB & RGBA color values, the transparent value, HSL & HSLA color values, the extended color keywords, the currentColor value, and the CSS2 UI colors. Note that when currentColor is used, it refers to the current animated value of the ‘color’ property.
<gradient>
A CSS gradient value as defined in CSS Image Values and Replaced Content Module Level 3. Percentage values are resolved against the bounding box of the element to which the gradient is applied.
<color>? <icccolor>
An ICC color [ICC42] with an optional sRGB fallback color if the ICC color cannot be used. The user agent searches the color profile description database for a color profile description entry whose name descriptor matches the <author-ident> part of the <icccolor> and uses the last matching entry that is found. If no match is found, then the sRGB fallback color is used instead, if provided; otherwise the document is in error (see Error processing). The comma and/or whitespace separated list of <number>s within the <icccolor> is a set of ICC-profile-specific color values. (In most cases, the <number>s will be in the range 0 to 1.) Note that color interpolation occurs in an RGB color space even if an ICC-based color specification is provided (see ‘color-interpolation’). For more on ICC-based colors, refer to Color profile descriptions.
[ <funciri> | child | <child-selector> ] [ none | <color> | [ <color>? <icccolor> ] ]?
A reference to a paint server element with an optional fallback color or none. The <funciri>, child keyword, or <child-selector> is used to identify a solidColor element, gradient element or pattern element, which defines the paint to use. The child keyword in this instance matches the last child paint server element of the element where the paint value is specified. If the reference is not valid (e.g., it points to an element that does not exist, no element was matched, or the element is not a valid paint server), then the fallback value is used, if provided; otherwise, the document is in error (see Error processing).
context-fill
context-stroke
The same paint as the computed value of the ‘fill’ or ‘stroke’ property, respectively, of the context element. If there is no context element, then no paint is applied. If the referenced paint is a gradient or a pattern, then the coordinate space to use and the object used for any 'objectBoundingBox'-relative values are the same as those of the context element.

11.3. Fill properties

11.3.1. Specifying fill paint: the ‘fill’ property

Name: fill
Value: <paint>
Initial: black
Applies to: shapes and text content elements
Inherited: yes
Percentages: N/A
Media: visual
Computed value: as specified, but with <color> values computed and <funciri> values made absolute
Animatable: yes

The ‘fill’ property paints the interior of the given graphical element. The area to be painted consists of any areas inside the outline of the shape. To determine the inside of the shape, all subpaths are considered, and the interior is determined according to the rules associated with the current value of the ‘fill-rule’ property. The zero-width geometric outline of a shape is included in the area to be painted.

The fill operation fills open subpaths by performing the fill operation as if an additional "closepath" command were added to the path to connect the last point of the subpath with the first point of the subpath. Thus, fill operations apply to both open subpaths within path elements (i.e., subpaths without a closepath command) and polyline elements.

11.3.2. Winding rule: the ‘fill-rule’ property

Name: fill-rule
Value: nonzero | evenodd
Initial: nonzero
Applies to: shapes and text content elements
Inherited: yes
Percentages: N/A
Media: visual
Computed value: as specified
Animatable: yes

The ‘fill-rule’ property indicates the algorithm (or winding rule) which is to be used to determine what parts of the canvas are included inside the shape. For a simple, non-intersecting path, it is intuitively clear what region lies "inside"; however, for a more complex path, such as a path that intersects itself or where one subpath encloses another, the interpretation of "inside" is not so obvious.

The ‘fill-rule’ property provides two options for how the inside of a shape is determined:

nonzero

This rule determines the "insideness" of a point on the canvas by drawing a ray from that point to infinity in any direction and then examining the places where a segment of the shape crosses the ray. Starting with a count of zero, add one each time a path segment crosses the ray from left to right and subtract one each time a path segment crosses the ray from right to left. After counting the crossings, if the result is zero then the point is outside the path. Otherwise, it is inside. The following drawing illustrates the nonzero rule:

Image showing nonzero fill rule

The effect of a nonzero fill rule on paths with self-intersections and enclosed subpaths.

evenodd

This rule determines the "insideness" of a point on the canvas by drawing a ray from that point to infinity in any direction and counting the number of path segments from the given shape that the ray crosses. If this number is odd, the point is inside; if even, the point is outside. The following drawing illustrates the evenodd rule:

Image showing evenodd fill rule

The effect of an evenodd fill rule on paths with self-intersections and enclosed subpaths.

The above descriptions do not specify what to do if a path segment coincides with or is tangent to the ray. Since any ray will do, one may simply choose a different ray that does not have such problem intersections.

11.3.3. Fill paint opacity: the ‘fill-opacity’ property

Name: fill-opacity
Value: <number>
Initial: 1
Applies to: shapes and text content elements
Inherited: yes
Percentages: N/A
Media: visual
Computed value: as specified, but clamped to the range [0, 1]
Animatable: yes

fill-opacity’ specifies the opacity of the painting operation used to paint the interior the current object. (See Painting shapes and text.) A value of 0 means fully transparent, and a value of 1 means fully opaque.

See also the ‘opacity’ property, which specifies group opacity.

11.4. Stroke properties

SVG 2 Requirement: Support non-scaling stroke.
Resolutions: SVG 2 will include non-scaling stroke.
SVG 2 will have the ‘vector-effect’ property.
Purpose: To support strokes whose width does not change when zooming a page, as common for example in maps.
Owner: Chris or Erik (no action)
Note: Note that this could be part of more generic non-scaling features.

The following are the properties which affect how an element is stroked.

In all cases, all stroking properties which are affected by directionality, such as those having to do with dash patterns, must be rendered such that the stroke operation starts at the same point at which the graphics element starts. In particular, for path elements, the start of the path is the first point of the initial "moveto" command.

For stroking properties such as dash patterns whose computations are dependent on progress along the outline of the graphics element, distance calculations are required to utilize the SVG user agent's standard Distance along a path algorithms.

When stroking is performed using a complex paint server, such as a gradient or a pattern, the stroke operation must be identical to the result that would have occurred if the geometric shape defined by the geometry of the current graphics element and its associated stroking properties were converted to an equivalent path element and then filled using the given paint server.

11.4.1. Specifying stroke paint: the ‘stroke’ property

Name: stroke
Value: <paint>
Initial: none
Applies to: shapes and text content elements
Inherited: yes
Percentages: N/A
Media: visual
Computed value: as specified, but with <color> values computed and <funciri> values made absolute
Animatable: yes

The ‘stroke’ property paints along the outline of the given graphical element.

A subpath (see Paths) consisting of a single moveto shall not be stroked. Any zero length subpath shall not be stroked if the ‘stroke-linecap’ property has a value of butt but shall be stroked if the ‘stroke-linecap’ property has a value of round or square, producing respectively a circle or a square centered at the given point. Examples of zero length subpaths include 'M 10,10 L 10,10', 'M 20,20 h 0', 'M 30,30 z' and 'M 40,40 c 0,0 0,0 0,0'.

SVG 2 Requirement: Include a way to specify stroke position.
Resolution: SVG 2 shall include a way to specify stroke position.
Purpose: To allow a stroke to be inside or outside the path.
Owner: Cameron (ACTION-3162)
Note: See proposal page.
SVG 2 Requirement: Allow more author control over positions of dashes.
Resolution: SVG 2 shall allow more author control over positions of dashes.
Purpose: To allow things like aligning dashes at rectangle corners or along paths, needed for mapping.
Owner: Cameron (ACTION-3163)
Note: See proposal page.

11.4.2. Stroke paint opacity: the ‘stroke-opacity’ property

Name: stroke-opacity
Value: <number>
Initial: 1
Applies to: shapes and text content elements
Inherited: yes
Percentages: N/A
Media: visual
Computed value: as specified, but clamped to the range [0, 1]
Animatable: yes

The ‘stroke-opacity’ property specifies the opacity of the painting operation used to stroke the current object. (See Painting shapes and text.) As with ‘fill-opacity’, a value of 0 means fully transparent, and a value of 1 means fully opaque.

See also the ‘opacity’ property, which specifies group opacity.

11.4.3. Stroke width: the ‘stroke-width’ property

Name: stroke-width
Value: <percentage> | <length>
Initial: 1
Applies to: shapes and text content elements
Inherited: yes
Percentages: refer to the size of the current viewport (see Units)
Media: visual
Computed value: as specified
Animatable: yes

This property specifies the width of the stroke on the current object. A zero value causes no stroke to be painted. A negative value is invalid.

11.4.4. Drawing caps at the ends of strokes: the ‘stroke-linecap’ property

Name: stroke-linecap
Value: butt | round | square
Initial: butt
Applies to: shapes and text content elements
Inherited: yes
Percentages: N/A
Media: visual
Computed value: as specified
Animatable: yes

stroke-linecap’ specifies the shape to be used at the end of open subpaths when they are stroked. The possible values are:

butt
This value indicates that the stroke for each subpath does not extend beyond its two endpoints. A zero length subpath will therefore not have any stroke.
round

This value indicates that at each end of each subpath, the shape representing the stroke will be extended by a half circle with a radius equal to the stroke width. If a subpath has zero length, then the resulting effect is that the stroke for that subpath consists solely of a full circle centered at the subpath's point.

square

This value indicates that at the end of each subpath, the shape representing the stroke will be extended by a rectangle with the same width as the stroke width and whose length is half of the stroke width. If a subpath has zero length, then the resulting effect is that the stroke for that subpath consists solely of a square with side length equal to the stroke width, centered at the subpath's point, and oriented such that two of its sides are parallel to the effective tangent at that subpath's point. See ‘path’ element implementation notes for details on how to determine the tangent at a zero-length subpath.

Image showing three paths, each with a different line cap.

The three types of line caps.

See the definition of the cap shape below for a more precise description of the shape a line cap will have.

11.4.5. Controlling line joins: the ‘stroke-linejoin’ and ‘stroke-miterlimit’ properties

Name: stroke-linejoin
Value: miter | round | bevel | arcs
Initial: miter
Applies to: shapes and text content elements
Inherited: yes
Percentages: N/A
Media: visual
Computed value: as specified
Animatable: yes

stroke-linejoin’ specifies the shape to be used at the corners of paths or basic shapes when they are stroked. For further details see the path implementation notes.

miter
This value indicates that a sharp corner is to be used to join path segments. The corner is formed by extending the outer edges of the stroke at the tangents of the path segments until they intersect.
round
This value indicates that a round corner is to be used to join path segments. The corner is a circular sector centered on the join point.
bevel
This value indicates that a bevelled corner is to be used to join path segments. The bevel shape is a triangle that fills the area between the two stroked segments.
arcs
This value indicates that an arcs corner is to be used to join path segments. The arcs shape is formed by extending the outer edges of the stroke at the join point with arcs that have the same curvature as the outer edges at the join point.

Is there a better name than arcs for this property value? I (Tav) prefer talon (as in bird claw). The term arc has other uses in SVG and in graphics in general. The term talon would be unique as well as fit in with the existing property value names for line-join.

How does the miter limit apply? (It's hard to get really long joins.) Do you fall back to miter or bevel? (Probably miter as it is more in the style.)

The arcs value is new in SVG 2. It was added to provide a better looking join when the path segments at the join are curved.

Adding new line join was approved at Rigi Kaltbad group meeting.

Image showing four paths, each with a different line join.

The four types of line joins.

Name: stroke-miterlimit
Value: <number>
Initial: 4
Applies to: shapes and text content elements
Inherited: yes
Percentages: N/A
Media: visual
Computed value: as specified
Animatable: yes

When two line segments meet at a sharp angle and miter joins have been specified for ‘stroke-linejoin’, it is possible for the miter to extend far beyond the thickness of the line stroking the path. The ‘stroke-miterlimit’ imposes a limit on the ratio of the miter length to the ‘stroke-width’. When the limit is exceeded, the join is converted from a miter to a bevel.

How should this apply to arcs line-joins?

<number>
The limit on the ratio of the miter length to the ‘stroke-width’. The value of <miterlimit> must be a <number> greater than or equal to 1. Any other value is an error (see Error processing).

The ratio of miter length (distance between the outer tip and the inner corner of the miter) to ‘stroke-width’ is directly related to the angle θ between the segments in user space by the formula:

miterLength ‘stroke-width’ = 1 sin θ 2
miterLength / stroke-width = 1 / sin(theta / 2)

For example, a miter limit of 1.414 converts miters to bevels for theta less than 90 degrees, a limit of 4.0 converts them for theta less than approximately 29 degrees, and a limit of 10.0 converts them for theta less than approximately 11.5 degrees.

See the definition of the line join shape below for a more precise description of the shape a line join will have.

11.4.6. Dashing strokes: the ‘stroke-dasharray’ and ‘stroke-dashoffset’ properties

Name: stroke-dasharray
Value: none | <dasharray>
Initial: none
Applies to: shapes and text content elements
Inherited: yes
Percentages: refer to the size of the current viewport (see Units)
Media: visual
Computed value: as specified
Animatable: yes (non-additive)

where:

<dasharray> = [ <length> | <percentage> ]#*

The ‘stroke-dasharray’ property controls the pattern of dashes and gaps used to form the shape of a path's stroke.

none
Indicates that no dashing is used.
<dasharray>

Specifies a dashing pattern to use. A <dasharray> is a list of comma and/or white space separated lengths and percentages. Each value specifies a length along the path for which the stroke is to be painted (a dash) and not painted (a gap). Every second value in the list beginning with the first one specifies the length of a dash, and every other value specifies the length of a gap between the dashes. If the list has an odd number of values, then it is repeated to yield an even number of values. (Thus, the rendering behavior of stroke-dasharray: 5,3,2 is equivalent to stroke-dasharray: 5,3,2,5,3,2.)

The resulting even-length dashing pattern is repeated along each subpath. The dashing pattern is reset and begins again at the start of each subpath.

If any value in the list is negative, the <dasharray> value is invalid. If all of the values in the list are zero, then the stroke is rendered as if a value of none were specified.

Image showing a thick, dashed stroke.

A dashed stroke. The dashing pattern is 20,10. The red line shows the actual path that is stroked.

Name: stroke-dashoffset
Value: <length> | <percentage>
Initial: 0
Applies to: shapes and text content elements
Inherited: yes
Percentages: refer to the size of the current viewport (see Units)
Media: visual
Computed value: as specified
Animatable: yes

The ‘stroke-dashoffset’ property specifies the distance into the repeated dash pattern to start the stroke dashing at the beginning of the path. If the value is negative, then the effect is the same as dash offset d:

d = s - ‘stroke-dashoffset’ mod s
d = s - (abs(stroke-dashoffset) mod s)

where s is the sum of the dash array values.

Image showing a thick, dashed stroke with a non-zero dash offset.

A dashed stroke with a non-zero dash offset. The dashing pattern is 20,10 and the dash offset is 15. The red line shows the actual path that is stroked.

See the definition of dash positions below for a more precise description of positions along a path that dashes will be placed.

11.4.7. Computing the shape of the stroke

SVG 2 Requirement: Specify stroke dashing more precisely.
Resolution: SVG 2 shall specify stroke dashing more precisely.
Purpose: To define dash starting point on basic shapes and path segments.
Owner: Cameron (no action)

Something in this section needs to reference pathLength so that dash lengths are in the author's path length space.

The following algorithm describes what the shape of a path or basic shape's stroke is, taking into account the stroking properties above:

This should include text elements too, but should we keep stroke dashing on text?

  1. Let shape be an empty shape.
  2. Let path be the equivalent path of the element.
  3. For each subpath of path:
    1. Let positions be the dash positions for the subpath.
    2. For each pair <start, end> in positions:
      1. Let dash be the shape that includes, for all distances between start and end along the subpath, all points that lie on the line perpendicular to the subpath at that distance and which are within distance ‘stroke-width’ of the point on the subpath at that position.
      2. Set dash to be the union of dash and the starting cap shape for the subpath at position start.
      3. Set dash to be the union of dash and the ending cap shape for the subpath at position end.
      4. Let index and last be the indexes of the path segments in the subpath at distance start and end along the subpath.

        It does not matter whether any zero length segments are included when choosing index and last.

      5. While index < last:
        1. Set dash to be the union of dash and the line join shape for the subpath at segment index index.
        2. Set index to index + 1.
      6. Set shape to be the union of shape and stroke.
  4. Return shape.

The dash positions for a given subpath of the equivalent path of a path or basic shape is a sequence of pairs of values, which represent the starting and ending distance along the subpath for each of the dashes that form the subpath's stroke. It is determined as follows:

  1. Let pathlength be the length of the subpath.
  2. Let dashes be the list of values of ‘stroke-dasharray’ on the element, converted to user units, repeated if necessary so that it has an even number of elements; if the property has the value none, then the list has a single value 0.
  3. Let count be the number of values in dashes.
  4. Let sum be the sum of the values in dashes.
  5. If sum = 0, then return a sequence with the single pair <0, pathlength>.
  6. Let positions be an empty sequence.
  7. Let offset be the value of the ‘stroke-dashoffset’ property on the element.
  8. If offset is negative, then set offset to sum − abs(offset).
  9. Set offset to offset mod sum.
  10. Let index be the smallest integer such that sum(dashesi, 0 ≤ iindex) ≥ offset.
  11. Let dashlength be min(sum(dashesi, 0 ≤ iindex) − offset, pathlength).
  12. If index mod 2 = 0, then append to positions the pair <0, dashlength>.
  13. Let position be dashlength.
  14. While position < pathlength:
    1. Set index to (index + 1) mod count.
    2. Let dashlength be min(dashesindex, pathlengthposition).
    3. If index mod 2 = 0, then append to positions the pair <position, position + dashlength>.
    4. Set position to position + dashlength.
  15. Return positions.

The starting and ending cap shapes at a given position along a subpath are determined as follows:

  1. If ‘stroke-linecap’ is butt, then return an empty shape.
  2. Otherwise, if ‘stroke-linecap’ is round, then:
    1. If this is a starting cap, then return a semicircle of radius ‘stroke-width’ positioned such that:
      • Its straight edge is parallel to the line perpendicular to the subpath at distance position along it.
      • The midpoint of its straight edge is at the point that is along the subpath at distance position.
      • The direction from the midpoint of its arc to the midpoint of its straight edge is the same as the direction of the subpath at distance position along it.
    2. Otherwise, this is an ending cap. Return a semicircle of radius ‘stroke-width’ positioned such that:
      • Its straight edge is parallel to the line perpendicular to the subpath at distance position along it.
      • The midpoint of its straight edge is at the point that is along the subpath at distance position.
      • The direction from the midpoint of its straight edge to the midpoint of its arc is the same as the direction of the subpath at distance position along it.
  3. Otherwise, ‘stroke-linecap’ is square:
    1. If this is a starting cap, then return a rectangle with side lengths ‘stroke-width’ and ‘stroke-width’ / 2 positioned such that:
      • Its longer edges, A and B, are parallel to the line perpendicular to the subpath at distance position along it.
      • The midpoint of A is at start.
      • The direction from the midpoint of B to the midpoint of A is the same as the direction of the subpath at distance position along it.
    2. Otherwise, this is an ending cap. Return a rectangle with side lengths ‘stroke-width’ and ‘stroke-width’ / 2 positioned such that:
      • Its longer edges, A and B, are parallel to the line perpendicular to the subpath at distance position along it.
      • The midpoint of A is at end.
      • The direction from the midpoint of A to the midpoint of B is the same as the direction of the subpath at distance position along it.
Image showing how to construct the three types of line caps

The three different ‘stroke-linecap’ values used on paths with a single, non-zero length subpath. The white line is the path itself and the thick gray area is the stroke. On the top row, the green lines indicate the perpendicular to the tangent at the path endpoints and the pink areas are the caps. The bottom row shows the stroke without the perpendicular and cap highlighting.

The line join shape for a given segment of a subpath is determined as follows:

  1. Let P be the point at the end of the segment.
  2. Let A be the line parallel to the tangent at the end of the segment.
  3. Let B be the line parallel to the tangent at the start of the following segment.
  4. If A and B are the same line, then return an empty shape.
  5. Let Aleft and Aright be lines parallel to A at a distance of ‘stroke-width’ / 2 to the left and to the right of A, respectively.
  6. Let Bleft and Bright be lines parallel to B at a distance of ‘stroke-width’ / 2 to the left and to the right of B, respectively.
  7. Let P1, P2 and P3 be points determined as follows:
    1. If the acute angle between A and B is on the right of these lines, considering the direction of the subpath, then P1 and P2 are the points on Aleft and Bleft closest to P, and P3 is the intersection of Aleft and Bleft.
    2. Otherwise, P1 and P2 are the points on Aright and Bright closest to P, and P3 is the intersection of Aright and Bright.
  8. Let bevel be the triangle formed from the three points P, P1 and P2.
  9. If ‘stroke-linejoin’ is round, then return the union of bevel and a circular sector of radius ‘stroke-width’, centered on P, and which has P1 and P2 as the two endpoints of the arc.
  10. If ‘stroke-linejoin’ is arcs, then find the circles that are tangent to the stroke edges at P1 and P2 with the same curvature as the edges at those points (see below). If both curvatures are zero fall through to miter. Extend the stroke edges using these circles (or a line, in the case of zero curvature). If the two circles (or circle and line) intersect, return the area inside the region defined by the lines that connect P with P1 and P2 and the arcs defined by the circles (or arc and line) between the closest intersection point to P, and P1 and P2. If the two circles (or circle and line) do not intersect, fall through to miter. Note that the curvatures are calculated in user-space before any transforms are applied.
  11. Let θ be the angle between A and B.
  12. If ‘stroke-linejoin’ is miter and 1 / sin(θ / 2) ≤ ‘stroke-miterlimit’, then return the union of bevel and the triangle formed from the three points P1, P2 and P3.
  13. Return bevel.
Image showing the lines and points computed to construct a round line join.

Construction of a round line join shape, shown in pink. The white line is the original path, which has two segments that come to a point, and the gray region is the stroke.

Image showing the lines and points computed to construct an arcs line join.

Construction of an arcs line join shape, shown in pink. The white line is the original path, which has two segments that come to a point, and the gray region is the stroke. The dashed lines show circles that are tangent to and have the curvature of the segments at the join. The olive-green circles (concentric with the dashed circles) define the join shape.

11.4.8. Computing the circles for the arcs 'stroke-linejoin'

The arcsstroke-linejoin’ requires finding circles that are both tangent to and have the same curvatures as the outer stroke edges at the ends of path segments. To find one of these circles, first calculate the curvature κ of the path segment at its end (see below). Next, find the radius of a circle corresponding to this curvature: r = 1/κ. Increase or decrease the radius by one half of the stroke width to account for the stroke: rc = r ± ½ stroke-width. The center of the circle will be on a line normal to the path end a distance of rc away from the outer stroke edge at the end.

For a line: the curvature is infinite. Extend the outer stroke edge by a line.

For an elliptical arc:

Need to do. This isn't as trivial as it first looks since we have to deal with rx != ry and an arbitrary rotation.

For a quadratic Bézier:

κ ( 0 ) = 1 2 ( P 1 P 0 ) × ( P 2 P 1 ) | P 1 P 0 | 3
$$\kappa(0) = {2\over3}{(P_1-P_0)\times((P_0-P_1)+(P_2-P_1))\over|P_1-P_0|^3}$$
κ ( 1 ) = 1 2 ( P 2 P 1 ) × ( P 0 P 1 ) | P 2 P 1 | 3
$$\kappa(0) = {2\over3}{(P_1-P_0)\times((P_0-P_1)+(P_2-P_1))\over|P_1-P_0|^3}$$

Where κ(0) and κ(1) are the signed curvatures at the start and end of the path segment respectively, and the P's are the three points that define the quadratic Bézier.

For a cubic Bézier:

κ ( 0 ) = 2 3 ( P 1 P 0 ) × ( P 2 P 1 ) | P 1 P 0 | 3
$$\kappa(0) = {2\over3}{(P_1-P_0)\times((P_0-P_1)+(P_2-P_1))\over|P_1-P_0|^3}$$
κ ( 1 ) = 2 3 ( P 3 P 2 ) × ( P 1 P 2 ) | P 3 P 2 | 3
$$\kappa(1) = {2\over3}{(P_3-P_2)\times((P_1-P_2)+(P_3-P_2))\over|P_3-P_2|^3}$$

Where κ(0) and κ(1) are the signed curvatures at the start and end of the path segment respectively, and the P's are the four points that define the cubic Bézier. Note, if P0 and P1, or P2 and P3 are degenerate, the curvature will be infinite and a line should be used in constructing the join.

11.5. Controlling visibility: the effect of the ‘display’ and ‘visibility’ properties

See the CSS 2.1 specification for the definitions of ‘display’ and ‘visibility’. [CSS21]

SVG uses two properties to control the visibility of container elements, graphics elements and text content elements: ‘display’ and ‘visibility’.

When applied to certain container elements, graphics elements or text content elements, setting ‘display’ to none results in the element not becoming part of the rendering tree. Such elements and all of their descendants (regardless of their own ‘display’ property value):

Elements that have any other ‘display’ value than none behave normally with respect to all of the above.

The ‘display’ property only applies to the following SVG elements: svg, g, switch, a, foreignObject, graphics elements and text content elements. Note that ‘display’ is not an inherited property.

The ‘display’ property affects the direct processing of a given element, but it does not prevent it from being referenced by other elements. For example, setting display: none on a path element will prevent that element from getting rendered directly onto the canvas, but the path element can still be referenced by a textPath element; furthermore, its geometry will be used in text-on-a-path processing even if the path has display: none.

When applied to a graphics element or text content element, setting ‘visibility’ to hidden or collapse results in the element not being painted. It is, however, still part of the rendering tree, is sensitive to pointer events (depending on the value of ‘pointer-events’), contributes to bounding box calculations and clipping paths, and does affect text layout.

The ‘visibility’ property only applies to graphics elements and text content elements. Note that since ‘visibility’ is an inherited property, although it has no effect on a container element itself, its inherited value can affect descendant elements.

11.6. Non-scaling stroke

Sometimes it is of interest to let the outline of an object keep its original width no matter which transforms are applied to it. For example, in a map with a 2px wide line representing roads it is of interest to keep the roads 2px wide even when the user zooms into the map. To achieve this, SVG Tiny 1.2 introduces the 'vector-effect' property. Future versions of the SVG language will allow for more powerful vector effects through this property but this version restricts it to being able to specify the non-scaling stroke behavior.

Name: vector-effect
Value: non-scaling-stroke | none
Initial: none
Applies to: graphics elements
Inherited: no
Percentages: N/A
Media: visual
Computed value: as specified
Animatable: yes
none
Specifies that no vector effect shall be applied, i.e. the default rendering behaviour from SVG 1.1 is used which is to first fill the geometry of a shape with a specified paint, then stroke the outline with a specified paint.
non-scaling-stroke
Modifies the way an object is stroked. Normally stroking involves calculating stroke outline of the shape's path in current user space and filling that outline with the stroke paint (color or gradient). With the non-scaling-stroke vector effect, stroke outline shall be calculated in the "host" coordinate space instead of user coordinate space. More precisely: a user agent establishes a host coordinate space which in SVG Tiny 1.2 is always the same as "screen coordinate space". The stroke outline is calculated in the following manner: first, the shape's path is transformed into the host coordinate space. Stroke outline is calculated in the host coordinate space. The resulting outline is transformed back to the user coordinate system. (Stroke outline is always filled with stroke paint in the current user space). The resulting visual effect of this modification is that stroke width is not dependant on the transformations of the element (including non-uniform scaling and shear transformations) and zoom level.

Note: Future versions of SVG may allow ways to control the host coordinate system.

Below is an example of the non-scaling-stroke 'vector-effect'.

<?xml version="1.0"?>
<svg xmlns="http://www.w3.org/2000/svg" version="1.2" baseProfile="tiny"
     width="6cm" height="4cm" viewBox="0 0 600 400" 
     viewport-fill="rgb(255,150,200)">

  <desc>Example non-scaling stroke</desc>
  <rect x="1" y="1" width="598" height="398" fill="none" stroke="black"/>
  
  <g transform="scale(9,1)">
    <line stroke="black" stroke-width="5" x1="10" y1="50" x2="10" y2="350"/>
    <line vector-effect="non-scaling-stroke" stroke="black" stroke-width="5" 
        x1="32" y1="50" x2="32" y2="350"/>
    <line vector-effect="none" stroke="black" stroke-width="5" 
        x1="55" y1="50" x2="55" y2="350"/>
  </g>

</svg>

11.7. Markers

SVG 2 Requirement: Improve markers.
Resolution: We will improve markers for SVG 2.
Purpose: To solve the common problems authors have with SVG markers.
Owner: Cameron (ACTION-3286)

A marker is a graphical object that is painted at particular positions along a path, line, polyline or polygon element, together known as the markable elements. There are four ways markers can be placed on these elements:

There are probably better terms to use than "vertex" and "segment" markers. At least, "vertex" would go more naturally with "edge", but we should use more natural sounding names.

The graphics for a marker are defined by a marker element. The ‘marker-start’, ‘marker-end’, ‘marker-mid’, ‘marker-segment’ and ‘marker-pattern’ properties, together known as the marker properties, reference marker elements.

Markers can be animated, and as with use elements, the animated effects will show on all current uses of the markers within the document.

Markers on a given element are painted in the following order, from bottom to top:

11.7.1. The ‘marker’ element

‘marker’
Categories:
Container element
Content model:
Any number of the following elements, in any order:a, altGlyphDef, clipPath, color-profile, cursor, filter, font, font-face, foreignObject, image, marker, mask, script, style, switch, text, view
Attributes:
DOM Interfaces:

The marker element defines the graphics that are to be used for drawing markers on a markable element.

Attribute definitions:

Name Value Lacuna value Animatable
markerUnits strokeWidth | userSpaceOnUse strokeWidth yes

The markerUnits attribute defines the coordinate system for attributes markerWidth, markerHeight and the contents of the marker. Values have the following meanings:

strokeWidth
markerWidth, markerHeight and the contents of the marker represent values in a coordinate system which has a single unit equal the size in user units of the current stroke width (see the ‘stroke-width’ property) in place for the graphic object referencing the marker.
userSpaceOnUse
markerWidth, markerHeight and the contents of the marker represent values in the current user coordinate system in place for the graphic object referencing the marker (i.e., the user coordinate system for the element referencing the marker element via a marker property).
Name Value Lacuna value Animatable
markerWidth, markerHeight <length> 3 yes

The markerWidth and markerHeight attributes represent the size of the viewport into which the marker is to be fitted according to the viewBox and preserveAspectRatio attributes. A value of zero for either attribute results in nothing being rendered for the marker. A negative value for either attribute is an error (see Error processing).

Name Value Lacuna value Animatable
refX, refY <length> 0 yes

The refX and refY attributes define the reference point of the marker which is to be placed exactly at the marker's position on the markable element. They are interpreted as being in the coordinate system of the marker contents, after application of the viewBox and preserveAspectRatio attributes.

Name Value Lacuna value Animatable
orient auto | <angle> | <number> 0 yes (non-additive)

The orient attribute indicates how the marker is rotated when it is placed at its position on the markable element. Values have the following meaning:

'auto'

A value of 'auto' indicates that the marker is oriented such that its positive x-axis is pointing in the direction of the path at the point it is placed.

If the marker is a segment marker, then the direction the marker is oriented is, if considering the incoming and outgoing directions as unit vectors, in the direction of the sum of these two vectors. If this sum is zero, then the marker is oriented in the incoming direction.

If the marker is on the first or last vertex of a closed subpath, then the incoming direction taken from the final path segment and the outgoing direction is taken from:

  • the first path segment of the following subpath, if the following subpath does not begin with a 'moveto' command, and
  • the first path segment of the current subpath, if the following subpath does begin with a 'moveto' command or if there is no following subpath.
<angle>
<number>

An <angle> value represents the angle the marker's positive x-axis makes with the positive x-axis in the user space of the markable element, and a <number> value with no unit represents an angle in degrees. For example, if a value of '0' is given, then the marker will be drawn such that its x-axis will align with the x-axis of the user space of the graphic object referencing the marker. A value of '90deg' will result in the marker being drawn with its positive x-axis in the direction of the positive y-axis of the markable element's user space.

The orientation occurs after the marker has been fitted into its viewport. See the Details on how markers are rendered section below for an illustrative example.

Name Value Lacuna value Animatable
position <length> | <percentage> as if not specified yes

If the marker element is a child of a markable element, then the presence of a position attribute indicates that the marker is a positioned marker and that it will be painted at the specified distance along the path. If the value is negative or greater than the length of the path, then no marker will be painted. If this attribute is specified on a marker that is not a child of a markable element, then it has no effect beyond being exposed in the DOM.

Should a negative or greater than path length value be an "in error" / "unsupported" value?

Name Value Lacuna value Animatable
href <iri> as if not specified yes

When a marker element is being used as a positioned marker, the href attribute indicates that the marker referenced by the attribute is to be used as the definition of the marker. The graphical content of the referencing marker element and any of its attributes that affect marker processing are ignored. Authors must not place any child graphical content in the referencing marker or specify the viewBox, preserveAspectRatio, refX, refY, markerUnits, markerWidth, markerHeight or orient attributes on it.

We should say something about referencing marker elements that have an href with the marker properties. I suspect we should just allow this. Whether we want to allow the full element-referencing thing that you can do with gradients, with selective overriding of attributes, I'm not sure.

The contents of the marker are relative to a new coordinate system. The markerUnits attribute determines an initial scale factor for transforming the graphics in the marker into the user coordinate system for the referencing element. An additional set of transformations might occur if there is a viewBox attribute, in which case the coordinate system for the contents of the marker will be transformed due to the processing of attributes viewBox and preserveAspectRatio. If there is no viewBox attribute, then the assumed default value for the the viewBox attribute has the origin of the viewBox coincident with the origin of the viewport and the width/height of the viewBox the same as the width/height of the viewport.

The user agent style sheet sets the ‘overflow’ property for marker elements to hidden, which causes a rectangular clipping path to be created at the bounds of marker's viewport. Unless the ‘overflow’ property is overridden, any graphics within the marker which goes outside of the marker's viewport will be clipped.

Properties inherit into the marker element from its ancestors; properties do not inherit from the element referencing the marker element. Note however that by using the context-stroke value for the ‘fill’ or ‘stroke’ on elements in its definition, a single marker can be designed to match the style of the element referencing the marker.

marker elements are only rendered directly when they are used as children of a markable element and have a position attribute specified. This causes the marker to be painted as a positioned marker. All other marker elements are not rendered directly and must be referenced by one of the marker properties to be rendered. The ‘display’ property does not apply to the marker element; thus, marker elements are not directly rendered even if the ‘display’ property is set to a value other than none, and marker elements are available for referencing even when the ‘display’ property on the marker element or any of its ancestors is set to none. marker elements that are used as positioned markers can simultaneously be referenced by the marker properties to be used as segment markers and repeating markers.

Event attributes and event listeners attached to the contents of a marker element are not processed; only the rendering aspects of marker elements are processed.

Make interaction work on positioned markers.

The following example shows the use of positioned markers to place symbols at particular distances along a path.

<svg xmlns="http://www.w3.org/2000/svg"
     width="600" height="200" viewBox="0 0 600 200">

   <defs>
     <marker id="Square" markerWidth="10" markerHeight="10"
             refX="5" refY="5" orient="auto">
       <path d="M 5,1 L 9,5 5,9 1,5 z" fill="#6a9100"/>
     </marker>
     <marker id="Circle" markerWidth="10" markerHeight="10"
             refX="5" refY="5" orient="auto">
       <circle cx="5" cy="5" r="2" fill="dodgerblue"/>
     </marker>
   </defs>

   <path d="M 100,50 C 100,250 500,-50 300,150"
         fill="none" stroke="deeppink" stroke-width="3">
     <marker href="#Square" position="0"/>
     <marker href="#Square" position="100%"/>
     <marker href="#Circle" position="50px"/>
     <marker href="#Circle" position="calc(100% - 50px)"/>
     <marker refX="5" refY="5" position="50%">
       <!-- the cross -->
       <path d="M 3,3 L 7,7 M 3,7 L 7,3"
             fill="none" stroke="black" stroke-width="2"/>
     </marker>
   </path>
</svg>
Image showing the use of positioned markers.

Child marker elements are used to position two square and two circular markers. The cross marker is defined inline and does not need an ID.

11.7.2. Referencing ‘marker’ elements

A number of marker properties allow specifying a marker using a <marker-ref> value.

<marker-ref> =
none |
<funciri> |
child |
<child-selector>

Values have the following meaning

<funciri>
Indicates that the marker element referenced by the <funciri> value will be used. If the IRI reference is not valid (e.g., it points to an object that is undefined or the object is not a marker element), then the marker reference is also not valid.
child
Indicates that the last child marker element of the element where the property is specified will be used. If there is no such element, then the reference is not valid.
<child-selector>
Indicates that the first matching descendent marker specified by the <child-selector>, applied in the context of the element where the property is specified, will be used. If no element matches any of the selectors contained in the <child-selector>, or the first match is not a marker, then the reference is not valid.

11.7.3. Vertex markers: the ‘marker-start’, ‘marker-mid’ and ‘marker-end’ properties

Name: marker-start, marker-mid, marker-end
Value: none | <marker-ref>
Initial: none
Applies to: markable elements
Inherited: yes
Percentages: N/A
Media: visual
Computed value: as specified, but with <funciri> values (that are part of a <marker-ref>) made absolute
Animatable: yes

The ‘marker-start’ and ‘marker-end’ properties are used to specify the marker that will be drawn at the first and last vertices of the given markable element, respectively. ‘marker-mid’ is used to specify the marker that will be drawn at all other vertices (i.e., every vertex except the first and last). Possible values for ‘marker-start’, ‘marker-mid’ and ‘marker-end’ are:

none
Indicates that no marker symbol will be drawn at the given vertex or vertices.
<marker-ref>
Indicates that the marker element referenced by the <marker-ref> value will be drawn at the given vertex or vertices. If the reference is not valid, then no marker will be drawn at the given vertex or vertices.

For polygon elements, the last vertex is the same as the first vertex, and for path elements that end with a closed subpath, the last vertex is the same as the first vertex of that final subpath. In this case, if the value of ‘marker-end’ is not none, then it is possible that two markers will be rendered on that final vertex.

Note that ‘marker-start’ and ‘marker-end’ refer to the first and last vertex of the entire path, not each subpath.

The following example shows a triangular marker symbol used as a vertex marker to form an arrowhead at the end of two paths.

<svg xmlns="http://www.w3.org/2000/svg"
     width="275" height="200" viewBox="0 0 275 200">
  <defs>
    <marker id="Triangle" viewBox="0 0 10 10" refX="1" refY="5" 
            markerUnits="strokeWidth" markerWidth="4" markerHeight="3"
            orient="auto">
      <path d="M 0 0 L 10 5 L 0 10 z" fill="context-stroke"/>
    </marker>
  </defs>

  <g fill="none" stroke-width="10" marker-end="url(#Triangle)">
    <path stroke="crimson" d="M 100,75 C 125,50 150,50 175,75"/>
    <path stroke="olivedrab" d="M 175,125 C 150,150 125,150 100,125"/>
  </g>
</svg>
Image showing the use of an automatically oriented marker.

The triangle is placed at the end of the path and oriented automatically so that it points in the right direction. The use of context-stroke ensures the fill of the triangle matches the stroke of each path.

11.7.4. Segment markers: the ‘marker-segment’ property

Name: marker-segment
Value: none | <marker-ref>
Initial: none
Applies to: markable elements
Inherited: yes
Percentages: N/A
Media: visual
Computed value: as specified, but with <funciri> values (that are part of a <marker-ref>) made absolute
Animatable: yes

New in SVG 2. Added to allow automatically placing marker symbols on path edges, as is common in for example line graphs.

The ‘marker-segment’ property is used to specify the marker that will be drawn at the center of each length path segment. Possible values are:

none
Indicates that no marker symbol will be drawn at the given vertex or vertices.
<marker-ref>
Indicates that the marker element referenced by the <marker-ref> value will be drawn at the center of each path segment. If the reference is not valid, then no marker will be drawn at the path segment centers.

The following example shows the use of both vertex markers and segment markers to construct a line graph.

<svg xmlns="http://www.w3.org/2000/svg" width="400" height="200">

  <marker id="Circle" markerWidth="8" markerHeight="8" refX="4" refY="4"
          markerUnits="userSpaceOnUse">
    <circle cx="4" cy="4" r="3" fill="deeppink"/>
  </marker>

  <marker id="Cross" markerWidth="10" markerHeight="10" refX="0" refY="0"
          viewBox="-5 -5 10 10" markerUnits="userSpaceOnUse"
          fill="none">
    <path d="M -4,-4 L 4,4 M -4,4 L 4,-4" stroke="white" stroke-width="4"/>
    <path d="M -4,-4 L 4,4 M -4,4 L 4,-4" stroke="black" stroke-width="2"/>
  </marker>

  <!-- grid lines -->
  <path stroke="#888" d="M 40,20 360,20 M 40,40 360,40 M 40,60 360,60
                         M 40,80 360,80 M 40,100 360,100 M 40,120 360,120
                         M 40,140 360,140 M 40,160 360,160 M 40,180 360,180"/>

  <!-- the graph line -->
  <polyline points="50,100 100,20 150,50 200,130 250,80 300,170 350,100"
            fill="none" stroke="deeppink" stroke-width="2"
            marker="url(#Circle)" marker-segment="url(#Cross)"/>
</svg>
Image showing the use of segment markers.

Segment markers are used to place crosses at the center of each line segment in the line graph.

11.7.5. Repeating markers: the ‘marker-pattern’ property

Name: marker-pattern
Value: [ none | <length> | <percentage> | <marker-ref> ]+
Initial: none
Applies to: markable elements
Inherited: yes
Percentages: refer to the length of the path
Media: visual
Computed value: as specified, but with <funciri> values (that are part of a <marker-ref>) made absolute
Animatable: yes

New in SVG 2. Added to allow markers to be placed along a path at positions unrelated to the segments used to form the path.

The ‘marker-pattern’ property is used to specify a pattern of markers and gaps to be repeated along the length of the markable element. Values have the following meanings:

none
Indicates that no marker will be painted at the current position along the path.
<length>
<percentage>
Indicates the length of a gap in the repeated pattern of markers.
<marker-ref>
A reference to a marker that will be placed at the current position along the path. If the reference is not valid, then no marker will be drawn at the current position.

If a value other than none is given, and the sum of the <length>s and <percentage>s is not positive, then it is an invalid value.

Unlike vertex markers, the orientation of an orient="auto" repeating marker that happens to lie on a vertex does not take into account the incoming and outgoing directions. Instead, it is simply oriented such that its positive x-axis is aligned with the direction of the path at its position.

The following example shows the use of the ‘marker-pattern’ property to specify a repeating pattern of two different markers spaced along a path.

<svg xmlns="http://www.w3.org/2000/svg" width="600" height="200">

  <marker id="DoubleDash" markerWidth="8" markerHeight="12" refX="0" refY="0"
          viewBox="-4 -6 8 12" markerUnits="userSpaceOnUse" orient="auto">
    <rect x="-3" y="-5" width="2" height="10"/>
    <rect x="1" y="-5" width="2" height="10"/>
  </marker>
  <marker id="SingleDash" markerWidth="4" markerHeight="12" refX="0" refY="0"
          viewBox="-2 -6 4 12" markerUnits="userSpaceOnUse" orient="auto">
    <rect x="-1" y="-5" width="2" height="10"/>
  </marker>

  <path d="M 50,100 S 100,132 150,86 200,173 250,76 300,81
                      350,136 400,87 450,166 500,87 550,96"
        stroke="deeppink" stroke-width="2" fill="none"
        marker-pattern="40 url(#DoubleDash) 40 url(#SingleDash)"/>
</svg>
Image showing the use of repeating markers.

Markers specified with the ‘marker-pattern’ property are placed along the path at fixed distances, not relative to the path vertices.

11.7.6. Marker shorthand: the ‘marker’ property

Name: marker
Value:
[ none | <marker-ref> ]{1,4} [ / <‘marker-pattern’> ]?
Initial: not defined for shorthand properties
Applies to: markable elements
Inherited: yes
Percentages: N/A
Media: visual
Computed value: see individual properties
Animatable: yes

The ‘marker’ property sets values for the ‘marker-start’, ‘marker-mid’, ‘marker-end’, ‘marker-segment’ and ‘marker-pattern’ properties. Values for have the following meanings:

none | <marker-ref>
Sets ‘marker-start’, ‘marker-mid’ and ‘marker-end’ to the specified value, and sets ‘marker-segment’ and ‘marker-pattern’ to none.
[ none | <marker-ref> ]{2}
Sets ‘marker-start’ and ‘marker-end’ to the two values specified, and sets ‘marker-mid’, ‘marker-segment’ and ‘marker-pattern’ to none.
[ none | <marker-ref> ]{3}
Sets ‘marker-start’, ‘marker-mid’ and ‘marker-end’ to the three values specified, and sets ‘marker-segment’ and ‘marker-pattern’ to none.
[ none | <marker-ref> ]{4}
Sets ‘marker-start’, ‘marker-segment’, ‘marker-mid’ and ‘marker-end’ to the four <marker-ref> values specified, and sets ‘marker-pattern’ to none.
[ none | <marker-ref> ]{1,4} / <‘marker-pattern’>
Sets ‘marker-start’, ‘marker-segment’, ‘marker-mid’ and ‘marker-end’ to the four <marker-ref> values specified before the slash, and sets ‘marker-pattern’ to the value after the slash.
anything else
Sets ‘marker-start’, ‘marker-segment’, ‘marker-mid’ and ‘marker-end’ to none, and sets ‘marker-pattern’ to the specified value.

11.7.7. Knocking out the stroke: the ‘marker-knockout-left’ and ‘marker-knockout-right’ properties

The marker knockout properties are still under heavy development and are subject to change. Feedback on how authors might prefer to specify marker knockout shapes is welcome.

Name: marker-knockout-left, marker-knockout-right
Value: <knockout-offset> | <knockout-shape> [ at <knockout-offset> ]?
Initial: 0
Applies to: marker
Inherited: no
Percentages: see prose
Media: visual
Computed value: as specified
Animatable: yes

where:

<knockout-offset> =
[ <length> | <percentage> ]
<knockout-shape> =
[ <length> | <percentage> ] inverted? circle |
[ <length> | <percentage> ]{2} inverted? ellipse |
[ <length> | <percentage> ]{1,2} inverted? [ rectangle | triangle ]

New in SVG 2. Added to allow authors to specify parts of a stroke that should be clipped away when a marker is placed on a path. This helps with arrowheads, where the stroke must not be visible behind the pointy end, and with hollow markers as seen in metro maps, where the center of a marker is transparent and the stroke should not show through.

When specified on a marker element, the ‘marker-knockout-left’ and ‘marker-knockout-right’ properties together specify a shape to clip away when when painting the stroke of an element that uses the marker. ‘marker-knockout-left’ specifies the left side of the shape and ‘marker-knockout-right’ the right side. These two sides are joined together with straight lines.

The <knockout-offset> part of the value, if specified, is the offset from the marker position, outwards, along the tangent, that the knockout shape side is placed at. This is the knockout shape side position. If it is omitted, then the offset is assumed to be zero. The value can be negative. Percentage values refer to the width of the marker contents viewport.

The <knockout-shape> part of the value, if specified, is the left or right side of the knockout shape. Values have the following meanings:

[ <length> | <percentage> ]{2} inverted? ellipse

The knockout shape side is an arc. The lengths or percentages specified are the x-radius and y-radius of the ellipse from which the arc is taken. A length is interpreted as being in the marker contents coordinate system. If the first value is a percentage, then it refers to the width of the marker contents viewport, and if the second value is a percentage then it refers to the height of the marker contents viewport.

If the inverted keyword is not specified, then the arc is constructed by placing the center of the ellipse at the knockout shape side position. First we consider only the 180° arc of the ellipse which points in the direction of the start of the start of the path, if this is the left knockout shape side, or the end of the path if this is the right knockout shape side. If the y-radius is less than or equal to half of the stroke width of the path the marker is on, then this 180° arc is the final knockout shape side. Otherwise, we intersect the arc with the two lines that are offset, by half of the stroke width, from the tangent to the marker orientation. The resulting arc with its start and end points on these two lines is the final knockout shape side.

If the inverted keyword is specified, then the arc is constructed by placing the center of the ellipse at a distance of two times its x-radius along the tangent to the marker orientation, in the direction of the start of the path if this is the left knockout shape side, or the end of the path if this is the right knockout shape side. We consider only the 180° arc of the ellipse that is pointing in the opposite direction. If the y-radius is less or equal to half of the stroke width of the path the marker is on, then this 180° arc is the final knockout shape side. Otherwise, we intersect the arc with the two lines that are offset, by half of the stroke width, from the tangent to the marker orientation. The resulting arc with its side and end points on these two lines is the final knockout shape side.

[ <length> | <percentage> ] inverted? circle

The knockout shape side is an arc. The shape is computed in the same way as the ellipse shape, but with both radii of the ellipse being the specified length or percentage, and with a percentage referring to the size of the marker contents viewport.

[ <length> | <percentage> ]{1,2} inverted? rectangle

The knockout shape side comprises one or two rectangles. These rectangles are aligned such that their top and bottom edges are parallel to the tangent to the marker orientation. The length or percentage is a width and the second, if specified, is a height. Percentage values here refer to the width and height of the marker contents viewport, respectively.

If the inverted keyword is not specified, then the knockout shape side is a single rectangle. The width of the rectangle is the specified width value. The height of the rectangle is the maximum of the stroke width of the path on which the marker exists and the specified height value, if it is specified. If it is not specified, then the height of the rectangle is just the stroke width. The rectangle is posisioned such that the center of its right hand edge is positioned at the knockout shape side position and the extent of its width is in the direction of the start of the path, if this is the left knockout shape side, or the end of the path if this is the right knockout shape side.

If the inverted keyword is specified, then the knockout shape side comprises two rectangles. If the specified height is greater than or equal to the stroke width, then the height of these rectangles is zero; otherwise, their heights are half of the difference between the stroke width and the specified height. The top edge of one of the rectangles is half of the stroke width away from the marker orientation tangent line, with its bottom edge closer to the tangent line. The other rectangle has its bottom edge half of the stroke width away from the tangent line and its top edge closer to the tangent line. The right edges of the rectangles are aligned with each other and also with the line perpendicular to the marker orientation tangent line. The extent of the widths of the rectangles is in the direction of the start of the path, if this is the left knockout shape side, or the end of the path if this is the right knockout shape side.

[ <length> | <percentage> ]{1,2} inverted? rectangle

The knockout shape side comprises one or two rectangles. These rectangles are aligned such that their top and bottom edges are parallel to the tangent to the marker orientation. The length or percentage is a width and the second, if specified, is a height. Percentage values here refer to the width and height of the marker contents viewport, respectively.

If the inverted keyword is not specified, then the knockout shape side is a single rectangle. The width of the rectangle is the specified width value. The height of the rectangle is the maximum of the stroke width of the path on which the marker exists and the specified height value, if it is specified. If it is not specified, then the height of the rectangle is just the stroke width. The rectangle is posisioned such that the center of its right hand edge is positioned at the knockout shape side position and the extent of its width is in the direction of the start of the path, if this is the left knockout shape side, or the end of the path if this is the right knockout shape side.

If the inverted keyword is specified, then the knockout shape side comprises two rectangles. If the specified height is greater than or equal to the stroke width, then the height of these rectangles is zero; otherwise, their heights are half of the difference between the stroke width and the specified height. The top edge of one of the rectangles is half of the stroke width away from the marker orientation tangent line, with its bottom edge closer to the tangent line. The other rectangle has its bottom edge half of the stroke width away from the tangent line and its top edge closer to the tangent line. The right edges of the rectangles are aligned with each other and also with the line perpendicular to the marker orientation tangent line. The extent of the widths of the rectangles is in the direction of the start of the path, if this is the left knockout shape side, or the end of the path if this is the right knockout shape side.

[ <length> | <percentage> ]{1,2} inverted? triangle

...

A diagram showing the construction of these shapes would be helpful.

Need to define how the two shape sides are joined together. It's taking the top and bottom points from both shapes, drawing vertical lines to the edge of the stroke shape, then drawing two horizontal lines to join them together.

The two knockout shape sides must not intersect, although they may touch. If they do intersect, then no knockout is performed for that marker when painting the stroke.

For example, using 8px inverted triangle at -4px for ‘marker-knockout-left’ and 8px triangle for ‘marker-knockout-right’ is allowed, as the two straight lines that form the left shape side do not intersect with either of the two straight lines that form the right shape side. However, using 8px triangle at -4px for both properties would obviously cause an intersection, and so would not be allowed.

Image showing various marker knockout shapes.

An illustration of the use of inverted and non-inverted circle, rectangle and triangle knockout shapes, at both 0px and 10px offsets. The value beneath each pink stroke is used for both ‘marker-knockout-left’ and ‘marker-knockout-right’. (The marker itself here has no content and does not render anything.)

While this is nice for straight line segments, if the path is curved at the marker position then it might be preferable to have the knockout shapes aligned with the tangent at the knockout shape side position, rather than with the marker orientation. Especially if the knockout is being used as a fancy dash pattern. Then we would likely want to join the left and right sides of the shape with a curved shape (along the stroke) and not just a rectangle. If we allow this, then computing that shape is going to be hard, and will mean that determining whether the left and right sides of the knockout shape intersect, and determining what the intersections of all of the knockout shapes on a path are, is also going to be hard. Perhaps that can be handled by extending dashing line caps with these shapes rather than here? Regardless of whether it is handled by marker knockouts or new line caps, it's going to be non-trivial to compute the right shapes.

Another thing to note is that knockouts here are like setting up a clipping path to remove parts of the stroke when it's painted. That means that if the stroke intersects itself over the knockout areas, it's going to be knocked out of all bits of the stroke that go through those areas. That may or may not be fine depending on your use cases.

11.7.8. Details on how markers are rendered

Markers are drawn after the given object is filled and stroked.

For each marker that is drawn, a temporary new user coordinate system is established so that the marker will be positioned and sized correctly, as follows:

The rendering effect of a marker is as if the contents of the referenced marker element were deeply cloned into a separate non-exposed DOM tree for each instance of the marker. Because the cloned DOM tree is non-exposed, the SVG DOM does not show the cloned instance of the marker.

For user agents that support Styling with CSS, the conceptual deep cloning of the referenced marker element into a non-exposed DOM tree also copies any property values resulting from the CSS cascade ([CSS21], chapter 6) and property inheritance on the referenced element and its contents. CSS 2.1 selectors can be applied to the original (i.e., referenced) elements because they are part of the formal document structure. CSS 2.1 selectors cannot be applied to the (conceptually) cloned DOM tree because its contents are not part of the formal document structure.

For illustrative purposes, we'll repeat the marker example shown earlier:

<?xml version="1.0" standalone="no"?>
<svg width="4in" height="2in" 
     viewBox="0 0 4000 2000" version="1.1"
     xmlns="http://www.w3.org/2000/svg">
  <defs>
    <marker id="Triangle"
      viewBox="0 0 10 10" refX="0" refY="5" 
      markerUnits="strokeWidth"
      markerWidth="4" markerHeight="3"
      orient="auto">
      <path d="M 0 0 L 10 5 L 0 10 z" />
    </marker>
  </defs>
  <rect x="10" y="10" width="3980" height="1980"
       fill="none" stroke="blue" stroke-width="10" />
  <desc>Placing an arrowhead at the end of a path.
  </desc>
  <path d="M 1000 750 L 2000 750 L 2500 1250"
        fill="none" stroke="black" stroke-width="100" 
        marker-end="url(#Triangle)"  />
</svg>

The rendering effect of the above file will be visually identical to the following:

<?xml version="1.0" standalone="no"?>
<svg width="4in" height="2in" 
     viewBox="0 0 4000 2000" version="1.1"
     xmlns="http://www.w3.org/2000/svg">
  <desc>File which produces the same effect
      as the marker example file, but without
      using markers.
  </desc>
  <rect x="10" y="10" width="3980" height="1980"
       fill="none" stroke="blue" stroke-width="10" />
  <!-- The path draws as before, but without the marker properties -->
  <path d="M 1000 750 L 2000 750 L 2500 1250"
        fill="none" stroke="black" stroke-width="100"  />
  <!-- The following logic simulates drawing a marker 
       at final vertex of the path. -->
  <!-- First off, move the origin of the user coordinate system
       so that the origin is now aligned with the end point of the path. -->
  <g transform="translate(2500,1250)" >
    <!-- Rotate the coordinate system 45 degrees because
         the marker specified orient="auto" and the final segment
         of the path is going in the direction of 45 degrees. -->
    <g transform="rotate(45)" >
      <!-- Scale the coordinate system to match the coordinate system
           indicated by the 'markerUnits' attributes, which in this case has
           a value of 'strokeWidth'. Therefore, scale the coordinate system
           by the current value of the 'stroke-width' property, which is 100. -->
      <g transform="scale(100)" >
        <!-- Translate the coordinate system by 
             (-refX*viewBoxToMarkerUnitsScaleX, -refY*viewBoxToMarkerUnitsScaleY)
             in order that (refX,refY) within the marker will align with the vertex.
             In this case, we use the default value for preserveAspectRatio
             ('xMidYMid meet'), which means find a uniform scale factor
             (i.e., viewBoxToMarkerUnitsScaleX=viewBoxToMarkerUnitsScaleY)
             such that the viewBox fits entirely within the viewport ('meet') and 
             is center-aligned ('xMidYMid'). In this case, the uniform scale factor
             is markerHeight/viewBoxHeight=3/10=.3. Therefore, translate by
             (-refX*.3,-refY*.3)=(0*.3,-5*.3)=(0,-1.5). -->
        <g transform="translate(0,-1.5)" >
          <!-- There is an implicit clipping path because the user agent style
               sheet says that the 'overflow' property for markers has the value
               'hidden'. To achieve this, create a clipping path at the bounds
               of the viewport. Note that in this case the viewport extends
               0.5 units to the left and right of the viewBox due to 
               a uniform scale factor, different ratios for markerWidth/viewBoxWidth
               and markerHeight/viewBoxHeight, and 'xMidYMid' alignment -->
          <clipPath id="cp1" >
            <rect x="-0.5" y="0" width="4" height="3" />
          </clipPath>
          <g clip-path="url(#cp1)" >
            <!-- Scale the coordinate system by the uniform scale factor
                 markerHeight/viewBoxHeight=3/10=.3 to set the coordinate
                 system to viewBox units. -->
            <g transform="scale(.3)" >
              <!-- This 'g' element carries all property values that result from
                   cascading and inheritance of properties on the original 'marker' element.
                   In this example, neither fill nor stroke was specified on the 'marker'
                   element or any ancestors of the 'marker', so the initial values of
                   "black" and "none" are used, respectively. -->
             <g fill="black" stroke="none" >
                <!-- Expand out the contents of the 'marker' element. -->
                <path d="M 0 0 L 10 5 L 0 10 z" />
              </g>
            </g>
          </g>
        </g>
      </g>
    </g>
  </g>
</svg>

View this example as SVG (SVG-enabled browsers only)

11.8. Controlling paint operation order: the ‘paint-order’ property

SVG 2 Requirement: Support control of the order of filling, stroke and painting markers on shapes.
Resolution: SVG 2 will adopt the ‘paint-order’ property proposal, though possibly with a different name.
Purpose: To address the common desire to paint strokes below fills without having to duplicate an element.
Owner: Cameron (ACTION-3285)
Name: paint-order
Value: normal | [ fill || stroke || markers ]
Initial: normal
Applies to: graphics elements and text content elements
Inherited: yes
Percentages: N/A
Media: visual
Computed value: as specified
Animatable: yes

New in SVG 2. Added primarily to allow painting the stroke of text below its fill without needing to duplicate the text element.

The ‘paint-order’ property controls the order that the three paint operations that shapes and text are rendered with: their fill, their stroke and any markers they might have.

Is there a better name than ‘paint-order’?

When the value of this property is normal, the element is painted with the standard order of painting operations: the fill is painted first, then its stroke and finally its markers.

When any of the other keywords are used, the order of the paint operations for painting the element is as given, from left to right. If any of the three keywords are omitted, they are painted last, in the order they would be painted with paint-order: normal.

This mean that, for example, paint-order: stroke has the same rendering behavior as paint-order: stroke fill markers.

This does not affect interaction, but once the marker children proposal is added to the spec, it will be possible for marker elements to receive mouse events or not depending on the value of ‘paint-order’.

The Rendering chapter will need some changes to accommodate ‘paint-order’, and should probably gain a more precise description of exactly how an SVG fragment is rendered.

Should there be a way of addressing the individual types of markers – vertex & segment, repeating, positioned – given they are currently specified to render in that order?

The following example shows how the ‘paint-order’ property can be used to render stroked text in a more aesthetically pleasing manner.

<svg xmlns="http://www.w3.org/2000/svg"
     width="600" height="150" viewBox="0 0 600 150">

  <style>
    text {
      font: 80px bold sans-serif; stroke-linejoin: round;
      text-anchor: middle; fill: peachpuff; stroke: crimson;
    }
  </style>

  <text x="150" y="100" stroke-width="6px">pizazz</text>
  <text x="450" y="100" stroke-width="12px" paint-order="stroke">pizazz</text>
</svg>
Image showing the effect of paint-order.

Text painted with its stroke below the fill.

11.9. Color space for interpolation: the ‘color-interpolation’ property

Name: color-interpolation
Value: auto | sRGB | linearRGB
Initial: sRGB
Applies to: container elements, graphics elements, gradient elements, animate and animateColor
Inherited: yes
Percentages: N/A
Media: visual
Computed value: as specified
Animatable: yes

The SVG user agent performs color interpolations and compositing at various points as it processes SVG content. The ‘color-interpolation’ property controls which color space is used for the following graphics operations:

For filter effects, the ‘color-interpolation-filters’ property controls which color space is used. [FILTERS]

The ‘color-interpolation’ property chooses between color operations occurring in the sRGB color space or in a (light energy linear) linearized RGB color space. Having chosen the appropriate color space, component-wise linear interpolation is used. Possible values for ‘color-interpolation’ are:

auto
Indicates that the user agent can choose either the sRGB or linearRGB spaces for color interpolation. This option indicates that the author doesn't require that color interpolation occur in a particular color space.
sRGB
Indicates that color interpolation occurs in the sRGB color space.
linearRGB
Indicates that color interpolation occurs in the linearized RGB color space as described below.

The conversion formulas between the sRGB color space (i.e., nonlinear with 2.2 gamma curve) and the linearized RGB color space (i.e., color values expressed as sRGB tristimulus values without a gamma curve) can be found in the sRGB specification [SRGB]. For illustrative purposes, the following formula shows the conversion from sRGB to linearized RGB, where Csrgb is one of the three sRGB color components, Clinear is the corresponding linearized RGB color component, and all color values are between 0 and 1:

C linear = { C srgb 12.92 if  C srgb 0.04045 C srgb + 0.055 1.055 2.4 if  C srgb > 0.04045
if C_srgb <= 0.04045
  C_linear = C_srgb / 12.92
else if c_srgb > 0.04045
  C_linear = ((C_srgb + 0.055) / 1.055) ^ 2.4

Out-of-range color values, if supported by the user agent, also are converted using the above formulas. (See Clamping values which are restricted to a particular range.)

When a child element is blended into a background, the value of the ‘color-interpolation’ property on the child determines the type of blending, not the value of the ‘color-interpolation’ on the parent. For gradients which make use of the ‘xlink:href’ attribute to reference another gradient, the gradient uses the ‘color-interpolation’ property value from the gradient element which is directly referenced by the ‘fill’ or ‘stroke’ property. When animating colors, color interpolation is performed according to the value of the ‘color-interpolation’ property on the element being animated.

11.10. Rendering hints

11.10.1. The ‘color-rendering’ property

Name: color-rendering
Value: auto | optimizeSpeed | optimizeQuality
Initial: auto
Applies to: container elements, graphics elements, gradient elements, animate and animateColor
Inherited: yes
Percentages: N/A
Media: visual
Computed value: as specified
Animatable: yes

The creator of SVG content might want to provide a hint to the implementation about how to make speed vs. quality tradeoffs as it performs color interpolation and compositing. The ‘color-rendering’ property provides a hint to the SVG user agent about how to optimize its color interpolation and compositing operations. Possible values are:

auto
Indicates that the user agent shall make appropriate tradeoffs to balance speed and quality, but quality shall be given more importance than speed.
optimizeSpeed
Indicates that the user agent shall emphasize rendering speed over quality. For RGB display devices, this option will sometimes cause the user agent to perform color interpolation and compositing in the device RGB color space.
optimizeQuality
Indicates that the user agent shall emphasize quality over rendering speed.

color-rendering’ takes precedence over ‘color-interpolation-filters’. For example, assume color-rendering: optimizeSpeed and color-interpolation-filters: linearRGB. In this case, the SVG user agent should perform color operations in a way that optimizes performance, which might mean sacrificing the color interpolation precision as specified by color-interpolation-filters: linearRGB.

11.10.2. The ‘shape-rendering’ property

Name: shape-rendering
Value: auto | optimizeSpeed | crispEdges | geometricPrecision
Initial: auto
Applies to: shapes
Inherited: yes
Percentages: N/A
Media: visual
Computed value: as specified
Animatable: yes

The creator of SVG content might want to provide a hint to the implementation about what tradeoffs to make as it renders vector graphics elements such as path elements and basic shapes such as circles and rectangles. The ‘shape-rendering’ property provides these hints. Possible values are:

auto
Indicates that the user agent shall make appropriate tradeoffs to balance speed, crisp edges and geometric precision, but with geometric precision given more importance than speed and crisp edges.
optimizeSpeed
Indicates that the user agent shall emphasize rendering speed over geometric precision and crisp edges. This option will sometimes cause the user agent to turn off shape anti-aliasing.
crispEdges
Indicates that the user agent shall attempt to emphasize the contrast between clean edges of artwork over rendering speed and geometric precision. To achieve crisp edges, the user agent might turn off anti-aliasing for all lines and curves or possibly just for straight lines which are close to vertical or horizontal. Also, the user agent might adjust line positions and line widths to align edges with device pixels.
geometricPrecision
Indicates that the user agent shall emphasize geometric precision over speed and crisp edges.

11.10.3. The ‘text-rendering’ property

Name: text-rendering
Value: auto | optimizeSpeed | optimizeLegibility | geometricPrecision
Initial: auto
Applies to: text
Inherited: yes
Percentages: N/A
Media: visual
Computed value: as specified
Animatable: yes

The creator of SVG content might want to provide a hint to the implementation about what tradeoffs to make as it renders text. The ‘text-rendering’ property provides these hints. Possible values are:

auto
Indicates that the user agent shall make appropriate tradeoffs to balance speed, legibility and geometric precision, but with legibility given more importance than speed and geometric precision.
optimizeSpeed
Indicates that the user agent shall emphasize rendering speed over legibility and geometric precision. This option will sometimes cause the user agent to turn off text anti-aliasing.
optimizeLegibility
Indicates that the user agent shall emphasize legibility over rendering speed and geometric precision. The user agent will often choose whether to apply anti-aliasing techniques, built-in font hinting or both to produce the most legible text.
geometricPrecision
Indicates that the user agent shall emphasize geometric precision over legibility and rendering speed. This option will usually cause the user agent to suspend the use of hinting so that glyph outlines are drawn with comparable geometric precision to the rendering of path data.

11.10.4. The ‘image-rendering’ property

Name: image-rendering
Value: auto | optimizeQuality | optimizeSpeed
Initial: auto
Applies to: shapes
Inherited: yes
Percentages: N/A
Media: visual
Computed value: as specified
Animatable: yes

The creator of SVG content might want to provide a hint to the implementation about how to make speed vs. quality tradeoffs as it performs image processing. The ‘image-rendering’ property provides a hint to the SVG user agent about how to optimize its image rendering. Possible values are:

auto
Indicates that the user agent shall make appropriate tradeoffs to balance speed and quality, but quality shall be given more importance than speed. The user agent shall employ a resampling algorithm at least as good as nearest neighbor resampling, but bilinear resampling is strongly preferred. For Conforming High-Quality SVG Viewers, the user agent shall employ a resampling algorithm at least as good as bilinear resampling.
optimizeQuality
Indicates that the user agent shall emphasize quality over rendering speed. The user agent shall employ a resampling algorithm at least as good as bilinear resampling.
optimizeSpeed
Indicates that the user agent shall emphasize rendering speed over quality. The user agent should use a resampling algorithm which achieves the goal of fast rendering, with the requirement that the resampling algorithm shall be at least as good as nearest neighbor resampling. If performance goals can be achieved with higher quality algorithms, then the user agent should use the higher quality algorithms instead of nearest neighbor resampling.

In all cases, resampling must be done in a truecolor (e.g., 24-bit) color space even if the original data and/or the target device is indexed color.

11.10.5. The ‘buffered-rendering’ property

SVG 2 Requirement: Support a hint to indicate that an element's rendering should be cached.
Resolution: SVG 2 will add ‘buffered-rendering’, as implementor feedback indicates that it is needed.
Purpose: For caching rendered results for faster display.
Owner: Erik (no action)

The creator of SVG content might want to provide a hint to the implementation about how often an element is modified to make speed vs. memory tradeoffs as it performs rendering. The ‘buffered-rendering’ property provides a hint to the SVG user agent about how to buffer the rendering of elements:

Name: buffered-rendering
Value: auto | dynamic | static
Initial: auto
Applies to: container elements and graphics elements
Inherited: no
Percentages: N/A
Media: visual
Computed value: as specified
Animatable: yes
auto
Indicates that the user agent is expected to use a reasonable compromise between speed of update and resource allocation.
dynamic
Indicates that the element is expected to be modified often.
static
Indicates that the element is not expected to be modified often. This suggests that user agent may be able to allocate resources, such as an offscreen buffer, that would allow increased performance in redraw. It does not mean that the element will never change. If an element is modified when the value is 'static', then redraw might have reduced performance.

11.11. Inheritance of painting properties

The values of any of the painting properties defined in this chapter can be inherited from a given object's parent. Painting, however, is always done on each graphics element individually, never at the container element (e.g., a g) level. Thus, for the following SVG, even though the gradient fill is specified on the g, the gradient is simply inherited through the g element down into each rectangle, each of which is rendered such that its interior is painted with the gradient.

Any painting properties defined in terms of the object's bounding box use the bounding box of the graphics element to which the operation applies. Note that text elements are defined such that any painting operations defined in terms of the object's bounding box use the bounding box of the entire text element. (See the discussion of object bounding box units and text elements.)

The following example shows how painting properties are inherited from a g element to its child rect elements.

<svg xmlns="http://www.w3.org/2000/svg"
     width="350" height="100" viewBox="0 0 350 100">
  <defs>
    <linearGradient id="OrangeYellow" gradientUnits="objectBoundingBox">
      <stop offset="0%" stop-color="#F60"/>
      <stop offset="100%" stop-color="#FF6"/>
    </linearGradient>
  </defs>
  <g stroke="black" stroke-width="2px" fill="url(#OrangeYellow)">
    <rect x="50" y="25" width="100" height="50"/>
    <rect x="200" y="25" width="100" height="50"/>
  </g>
</svg>
Image demonstrating the inheritance of painting properties.

Both rectangles are filled with the same orange-to-yellow gradient.

11.12. DOM interfaces

11.12.1. Interface SVGPaint

interface SVGPaint : SVGColor { 

  // Paint Types
  const unsigned short SVG_PAINTTYPE_UNKNOWN = 0;
  const unsigned short SVG_PAINTTYPE_RGBCOLOR = 1;
  const unsigned short SVG_PAINTTYPE_RGBCOLOR_ICCCOLOR = 2;
  const unsigned short SVG_PAINTTYPE_NONE = 101;
  const unsigned short SVG_PAINTTYPE_CURRENTCOLOR = 102;
  const unsigned short SVG_PAINTTYPE_URI_NONE = 103;
  const unsigned short SVG_PAINTTYPE_URI_CURRENTCOLOR = 104;
  const unsigned short SVG_PAINTTYPE_URI_RGBCOLOR = 105;
  const unsigned short SVG_PAINTTYPE_URI_RGBCOLOR_ICCCOLOR = 106;
  const unsigned short SVG_PAINTTYPE_URI = 107;

  readonly attribute unsigned short paintType;
  readonly attribute DOMString uri;

  void setUri(DOMString uri);
  void setPaint(unsigned short paintType, DOMString uri, DOMString rgbColor, DOMString iccColor);
};

There are some missing definitions of SVGPaint members here. The interface might be going away, however.

11.12.2. Interface SVGMarkerInstance

The SVGMarkerInstance interface is used to represent an instance of a marker that is on a markable element. An SVGMarkerInstance can represent any kind of marker, including positioned markers.

What should we do about liveness? If it is live, we could have it know what index it is for, and always return information about the marker at that index (and return null for the element if that index is no longer valid).

interface SVGMarkerInstance {
  readonly attribute SVGMarkerElement element;
  readonly attribute float position;
  readonly attribute SVGPoint point;
  readonly attribute float angle;
};
Attributes:
element (readonly SVGMarkerElement)
The marker element that defines the marker. If the marker is a vertex marker, segment marker or repeating marker, then this will be the marker element that the relevant marker property referenced. If the marker is a positioned marker, then this will be the child marker element of the markable element.
position (readonly float)
The distance along the equivalent path of the markable element that the marker is positioned at.
point (readonly SVGPoint)
The point, in the user space of the markable element, that the marker is positioned at. The SVGPoint object is read only.
angle (readonly float)
The orientation of the marker relative to a vector pointing in the direction of the positive y-axis of the markable element's user space.

11.12.3. Interface SVGMarkerList

The SVGMarkerList interface is used to expose the list of markers that are painted on a given markable element. This list includes all vertex markers, segment markers, repeating markers and positioned markers. The list of SVGMarkerInstance objects is maintained in the order that the markers are painted (see Markers).

The supported property indices of an SVGPathSegList object is all non-negative integers less than the length of the list.

interface SVGMarkerList {
  readonly attribute unsigned long length;
  getter SVGMarkerInstance? item(unsigned long index);
};
Attributes:
length (readonly unsigned long)
The number of markers on this element.
Operations:
SVGMarkerInstance? item(unsigned long index)
Gets the SVGMarkerInstance at the given position in the list of markers on this element.
Parameters
  1. unsigned long index
    The index of the SVGMarkerInstance to return.
Returns
Returns the SVGMarkerInstance at position index in the list of markers on this element, or null if index is out of range.

11.12.4. Interface SVGMarkableElement

The SVGMarkableElement interface is implemented on all markable elements, and provides access to the markers that are placed on the element's path.

[NoInterfaceObject]
interface SVGMarkableElement {
  readonly attribute SVGMarkerList markers;

  long getMarkerIndexFromPoint(SVGPoint point);
};
Attributes:
markers (readonly SVGMarkerList)
The list of markers on this element.
Operations:
long getMarkerIndexFromPoint(SVGPoint point)
Returns the index into the SVGMarkerList of the marker that is at the specified point. Normal hit testing rules apply; the value of the ‘pointer-events’ property on the elements that comprise the markers, as well as its value on this element, is honored, and the top-most marker is selected when there are multiple markers whose content is at the given point.
Parameters
  1. SVGPoint point
    The point to check for intersection with the markers on this element. The SVGPoint is interpreted as a point in the user space of this element.
Returns
The index into this element's SVGMarkerList of the marker at the given point, or -1 if there is no such marker.

11.12.5. Interface SVGMarkerElement

The SVGMarkerElement interface corresponds to the marker element.
interface SVGMarkerElement : SVGElement {

  // Marker Unit Types
  const unsigned short SVG_MARKERUNITS_UNKNOWN = 0;
  const unsigned short SVG_MARKERUNITS_USERSPACEONUSE = 1;
  const unsigned short SVG_MARKERUNITS_STROKEWIDTH = 2;

  // Marker Orientation Types
  const unsigned short SVG_MARKER_ORIENT_UNKNOWN = 0;
  const unsigned short SVG_MARKER_ORIENT_AUTO = 1;
  const unsigned short SVG_MARKER_ORIENT_ANGLE = 2;

  readonly attribute SVGAnimatedLength refX;
  readonly attribute SVGAnimatedLength refY;
  readonly attribute SVGAnimatedEnumeration markerUnits;
  readonly attribute SVGAnimatedLength markerWidth;
  readonly attribute SVGAnimatedLength markerHeight;
  readonly attribute SVGAnimatedEnumeration orientType;
  readonly attribute SVGAnimatedAngle orientAngle;

  void setOrientToAuto();
  void setOrientToAngle(SVGAngle angle);
};

SVGMarkerElement implements SVGFitToViewBox;
Constants in group “Marker Unit Types”:
SVG_MARKERUNITS_UNKNOWN (unsigned short)
The marker unit type is not one of predefined types. It is invalid to attempt to define a new value of this type or to attempt to switch an existing value to this type.
SVG_MARKERUNITS_USERSPACEONUSE (unsigned short)
The value of attribute markerUnits is 'userSpaceOnUse'.
SVG_MARKERUNITS_STROKEWIDTH (unsigned short)
The value of attribute markerUnits is 'strokeWidth'.
Constants in group “Marker Orientation Types”:
SVG_MARKER_ORIENT_UNKNOWN (unsigned short)
The marker orientation is not one of predefined types. It is invalid to attempt to define a new value of this type or to attempt to switch an existing value to this type.
SVG_MARKER_ORIENT_AUTO (unsigned short)
Attribute orient has value 'auto'.
SVG_MARKER_ORIENT_ANGLE (unsigned short)
Attribute orient has an angle value.
Attributes:
refX (readonly SVGAnimatedLength)
Corresponds to attribute refX on the given marker element.
refY (readonly SVGAnimatedLength)
Corresponds to attribute refY on the given marker element.
markerUnits (readonly SVGAnimatedEnumeration)
Corresponds to attribute markerUnits on the given marker element. One of the Marker Unit Types defined on this interface.
markerWidth (readonly SVGAnimatedLength)
Corresponds to attribute markerWidth on the given marker element.
markerHeight (readonly SVGAnimatedLength)
Corresponds to attribute markerHeight on the given marker element.
orientType (readonly SVGAnimatedEnumeration)
Corresponds to attribute orient on the given marker element. One of the Marker Orientation Types defined on this interface.
orientAngle (readonly SVGAnimatedAngle)
Corresponds to attribute orient on the given marker element. If markerUnits is SVG_MARKER_ORIENT_ANGLE, the angle value for attribute orient; otherwise, it will be set to zero.
Operations:
void setOrientToAuto()
Sets the value of attribute orient to 'auto'.
void setOrientToAngle(SVGAngle angle)
Sets the value of attribute orient to the given angle.
Parameters
  1. SVGAngle angle
    The angle value to use for attribute orient.
SVG 2 – 09 April 2013 TopContentsPreviousNextElementsAttributesProperties