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.
Some graphics elements – ‘path’ elements and basic shapes – 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.
SVG 2 adds markers on shapes. Resolved at Tokyo F2F.
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) |
SVG 2 Addition: | Allow multiple paints in fill and stroke. |
---|---|
Resolution: | We will allow multiple paints in the fill and stroke properties in SVG 2. |
Purpose: | Useful for creating cross hatchings, putting a partially transparent pattern on top of a solid fill, etc. |
Owner: | Tav (ACTION-3500) |
Properties ‘fill
’ and ‘stroke
’ take on a comma separated list of values of type <paint>. Each paint is applied to an element in reverse order. Note, only a paint server in the last position may take an optional fallback color.
The ability to apply more than one paint to an element is new in SVG 2.
The paint order follows that of CSS backgrounds.
<rect width="100" height="100" fill="url(#MyHatch1), url(#MyHatch2), powderblue">
The type <paint> is defined as:
<paint> = [ <paint-layer> , ]* <final-paint-layer>
<paint-layer> = <paint-source>|| <position> [ / <paint-size> ]? || <repeat-style> || [ <shape-box> | fill | stroke | view-box ] || [ <shape-box> | fill | stroke | view-box ]
<final-paint-layer> = <paint-source> || <position> [ / <paint-size> ]? || <repeat-style> || [ <shape-box> | fill | stroke | view-box ] || [ <shape-box> | fill | stroke | view-box ] || <color>
<paint-source> = none | <image> | <url> | context-fill | context-stroke
Values have the following meaning:
color
’ property.Changed from SVG 1.1 behavior where document is in error if paint server missing or invalid.
<rect width="100" height="100" fill="url(#MyHatch1), url(#MyHatch2) powderblue">
How should 'child' behave with allowing multiple paints?
This section needs additional examples, especially one with 'child'.
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.Should gradient elements also be context elements?
See the CSS Color Module Level 3 specification for the
definition of ‘color
’.
[CSS3COLOR]
The ‘color
’ property is used to provide a potential indirect value,
currentColor, for the ‘fill
’,
‘stroke
’, ‘solid-color
’, ‘stop-color
’, ‘flood-color
’ and
‘lighting-color
’ properties. The property has no other effect
on SVG elements.
The following example shows how the inherited value of the
‘color
’ property from an HTML document can be used to
set the color of SVG text in an inline SVG fragment.
<!DOCTYPE html> <style> body { color: #468; font: 16px sans-serif } svg { border: 1px solid #888; background-color: #eee } </style> <p>Please see the diagram below:</p> <svg width="200" height="100"> <g fill="currentColor"> <text x="70" y="55" text-anchor="end">START</text> <text x="130" y="55">STOP</text> <path d="M 85,45 h 25 v -5 l 10,10 -10,10 v -5 h -25 z"/> </g> </svg>
Please see the diagram below:
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 <url> 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.
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:
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:
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:
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.
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.
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. |
In this section, we define a number of properties that allow the author to control different aspects of a stroke, including its paint, thickness, use of dashing, and joining and capping of path segments.
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.
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 <url> 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'.
The above paragraph should be redundant with the stroke shape computation requirements below. In this section, we should phrase the requirements descriptively rather than normatively.
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. |
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.
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: | absolute length or percentage |
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.
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:
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.
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.
See the definition of the cap shape below for a more precise description of the shape a line cap will have.
Name: | stroke-linejoin |
---|---|
Value: | miter | miter-clip | 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.
stroke-miterlimit
’
is exceeded, the line join falls back to bevel
(see below).stroke-miterlimit
’ is exceeded, the miter is clipped at a
miter length equal to the ‘stroke-miterlimit
’ value multiplied
by the stroke width (see below).The miter-clip and arcs values are new in SVG 2. The miter-clip value offers a more consistent presentation for a path with multiple joins as well as better behavior when a path is animated. The arcs value provides a better looking join when the path segments at the join are curved.
Adding 'arcs' line join was resolved at the Rigi Kaltbad group meeting.
Adding 'miter-clip' line join was resolved at the Sydney (2015) group meeting.
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 a value of
miter,
miter-clip, or
arcs has been specified for
‘stroke-linejoin
’, it is possible for the join to extend
far beyond the thickness of the line stroking the path. The
‘stroke-miterlimit
’ imposes a limit on the extent of the
line join.
stroke-width
’ value. The value of
‘stroke-miterlimit
’ must be a <number> greater
than or equal to 1. Any other value is an error (see
Error processing).
For the miter or the miter-clip values, given the angle θ between the segments in user space, the miter length is calculated by:
miter length = stroke-width / sin(theta / 2)
If the miter length divided by the stroke width exceeds the
‘stroke-miterlimit
’ then for the value:
For the arcs value, the
miter length is calculated along a circular arc that is
tangent to the line bisecting the angle between the two segments at
the point the two segments intersect and passes through the end
point of the join. The line join is clipped, if necessary, by a line
perpendicular to this arc at a miter length equal to the
value of the ‘stroke-miterlimit
’ value multiplied by the
stroke width.
The effect of 'stroke-miterlimit' on an 'arcs' line join was resolved at Sydney (2015) group meeting.
See the definition of the line join shape below for a more precise description of the shape a line join will have.
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: | absolute lengths or percentages for <dasharray>, or keyword specified |
Animatable: | yes (non-additive) |
where:
<dasharray> = [ <length> | <percentage> | <number> ]#*
The ‘stroke-dasharray
’ property controls
the pattern of dashes and gaps used to form the shape of
a path's stroke.
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.
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: | absolute length or percentage |
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 - (abs(stroke-dashoffset) mod s)
where s is the sum of the dash array values.
See the definition of dash positions below for a more precise description of positions along a path that dashes will be placed.
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 stroke shape of an element is the
shape that is filled by the ‘stroke
’ property. The following algorithm
describes what the stroke shape of a ‘path’ or basic shape is,
taking into account the stroking properties above:
This should include text elements too, but should we keep stroke dashing on text?
stroke-width
’ of
the point on the subpath at that position.It does not matter whether any zero length segments are included when choosing index and last.
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:
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.stroke-dashoffset
’
property on the element.The starting and ending cap shapes at a given position along a subpath are determined as follows:
stroke-linecap
’ is butt, then return an empty shape.stroke-linecap
’ is round, then:
stroke-width
’ positioned such that:
stroke-width
’ positioned such that:
stroke-linecap
’ is square:
stroke-width
’ and ‘stroke-width
’ / 2 positioned such that:
stroke-width
’ and ‘stroke-width
’ / 2 positioned such that:
The line join shape for a given segment of a subpath is determined as follows:
stroke-width
’ / 2 to the
left and to the right of A relative to the subpath direction, respectively.stroke-width
’ / 2 to the
left and to the right of B, relative to the subpath direction, respectively.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.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-clip.
Extend the stroke edges using these circles (or a line, in the case
of zero curvature). If the two circles (or circle and line) do not
intersect, fall through to miter-clip.
If the two circles (or circle and line) intersect, the line join
region is 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.
Next calculate the miter limit as defined in
the ‘stroke-miterlimit
’ section. Clip any part of the line
join region that extends past the miter limit. Return the
resulting region.
Note that the curvatures are calculated in user-space before any
transforms are applied.stroke-linejoin
’ is miter or
miter-clip then the line join
region is the union of bevel and the triangle formed
from the three points P1,
P2 and P3.
stroke-miterlimit
’, then return
the line join region.
stroke-linejoin
’ is miter-clip,
then clip any part of the line join region that extends past the
miter limit and return this region.
The arcs ‘stroke-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:
$$\kappa(t) = {{r_x r_y}\over{(r_x^2 \sin^2 t + r_y^2 \cos^2 t)^{3/2}}}$$
where:
$$t = \arctan ( {r_y \over r_x} \tan \theta )$$
The parameter θ at the beginning or end of an arc segment can be found by using the formulas in the Elliptical arc implementation notes. (Note, some renderers convert elliptical arcs to cubic Béziers prior to rendering so the equations here may not be needed.)
For a quadratic Bézier:
$$\kappa(0) = {2\over3}{(P_1-P_0)\times((P_0-P_1)+(P_2-P_1))\over|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}$$
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:
$$\kappa(0) = {2\over3}{(P_1-P_0)\times((P_0-P_1)+(P_2-P_1))\over|P_1-P_0|^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.
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.
SVG 2 Requirement: | SVG 2 will have constrained transformations based on SVG 1.2 Tiny. |
---|---|
Resolution: | Add vector effects extension proposal to SVG 2 specification. |
Purpose: | To include non-scaling features (non-scaling part of the object, and non-scaling entire object |
Owner: | Satoru Takagi (ACTION-3619) |
Sometimes it is of interest to let the outline of an object keep its original width or to let the position of an object fix 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, or introductory notes on the graphic chart in which panning is possible.
To offer such effects regarding special coordinate transformations and graphic drawings, SVG Tiny 1.2 introduces the ‘vector-effect
’ property. Although SVG Tiny 1.2 introduced only non-scaling stroke behavior, this version introduces a number of additional effects. Furthermore, since these effects can be specified in combination, they show more various effects. And, future versions of the SVG language will allow for more powerful vector effects through this property.
Name: | vector-effect |
---|---|
Value: | none | [non-scaling-stroke | non-scaling-size | non-rotation | fixed-position]+ [ viewport | screen ]? |
Initial: | none (When values except none are set, viewport becomes the another initial value.) |
Applies to: | graphics elements |
Inherited: | no |
Percentages: | N/A |
Media: | visual |
Computed value: | as specified |
Animatable: | yes |
transform
’ property, that property is consumed for this effect. The shift conponents e and f of matrix of ‘transform
’ property are used to transfer the origin of fixed user space. The transformation formula and the example behavior are indicated to the following chapter. These values can be enumerated. Thereby, the effect which has these characteristics simultaneously can be specified.
The following two values assists the above-mentioned values. They show the host coordinate space of constrained transformations. Especially it has effective for the element belonging to nested viewport coordinate system such as nested contents or nested ‘svg’ elements. An initial value in case it is not specified is viewport.
Note: Future versions of SVG may allow ways to specify the device coordinate system.
This section shows the list of transformation formulas regarding combinations of the values for clarification of the behavior of vector effects excluding non-scaling-stroke which has clear implications.
Based on Nested transformations section, the normal coordinate transformation formula from user coordinate system to viewport coordinate system is as follows.
The code assumes a 2D rendering context. Width CSS Transforms we get a 3D rendering context as well? How does that work on perspective or 3D transformations?
<circle vector-effect="veValue" transform="translate(xo yo)" cx="xf" cy="yf" r=".."/>
When the ‘vector-effect
’ is added to an element like the above, the transformation formula for user coordinate to the device coordinate changes as follows. Here, xf and yf are user coordinate of the corresponding element and its descendant. And, xo and yo are matrix element e and f of the transform attribute which the corresponding element has. In addition, |det(CTM)| is absolute value of the determinants of CTM. When this value becomes 0 and non-scaling-size is appointed, ‘vector-effect
’ becomes invalidity namely none.
veValue | Formula |
---|---|
non-scaling-size |
|
non-rotation |
|
non-scaling-size non-rotation |
|
fixed-position |
|
fixed-position non-scaling-size |
|
fixed-position non-rotation |
|
fixed-position non-scaling-size non-rotation |
|
Below is normal coordinate transformation formula for nested viewport coordinate systems without vector effects. xviewport(UA) and yviewport(UA) are coordinates which under the immediate control of user agent. CTMthis is CTM for the transformation matrix from user coordinate system of an target graphic to viewport coordinate system to which it belongs. CTMparent is CTM for the transformation matrix from aforementioned viewport coordinate system to viewport coordinate system of the parent of that. And, CTMroot is CTM for rootmost viewport coordinate system (UA).
When applying seven formulas of the preceding section to nested viewport coordinate systems, the application way of those formulas changes as follows by whether viewport or screen is specified as the additional value of ‘vector-effect
’.
When viewport value is specified, user agent computes coordinates combining either of seven formulas of the preceding chapter, and the following formulas.
When screen value is specified, user agent computes coordinates combining either of seven formulas of the preceding chapter, and the following formulas.
Below is an example of the non-scaling-stroke ‘vector-effect
’.
<?xml version="1.0"?> <svg xmlns="http://www.w3.org/2000/svg" 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>
Below is an example of the none ‘vector-effect
’ (no vector effect).
Before changing CTM | After changing CTM |
Source code
<svg xmlns="http://www.w3.org/2000/svg" viewBox="-50,-50,500,500" height="500" width="500"> <rect x="-50" y="-50" width="500" height="500" stroke="orange" stroke-width="3" fill="none"></rect> <!-- Nested user space is transformed by this transform attribute --> <g id="base" transform="matrix(2.1169438081370817,0.3576047954311102,-0.3576047954311102,1.4700998667618626,0,0) translate(-50,-50)"> <svg viewBox="-50,-50,500,500" height="500" width="500"> <!-- Graph paper on the this svg's base user space --> <g stroke="green" stroke-width="1" fill="none"> <circle cx="0" cy="0" r="10"></circle> <circle cx="150" cy="150" r="7"></circle> <path fill="green" stroke="none" d="M0,-3 L30,-3 25,-10 50,0 25,10 30,3 0,3z"></path> <line x1="-100" y1="-100" x2="600" y2="-100" stroke-dasharray="5,5"></line> <line x1="-100" y1="000" x2="600" y2="000"></line> <line x1="-100" y1="100" x2="600" y2="100" stroke-dasharray="5,5"></line> <line x1="-100" y1="200" x2="600" y2="200" stroke-dasharray="5,5"></line> <line x1="-100" y1="300" x2="600" y2="300" stroke-dasharray="5,5"></line> <line x1="-100" y1="400" x2="600" y2="400" stroke-dasharray="5,5"></line> <line x1="-100" y1="500" x2="600" y2="500" stroke-dasharray="5,5"></line> <line y1="-100" x1="-100" y2="600" x2="-100" stroke-dasharray="5,5"></line> <line y1="-100" x1="000" y2="600" x2="000"></line> <line y1="-100" x1="100" y2="600" x2="100" stroke-dasharray="5,5"></line> <line y1="-100" x1="200" y2="600" x2="200" stroke-dasharray="5,5"></line> <line y1="-100" x1="300" y2="600" x2="300" stroke-dasharray="5,5"></line> <line y1="-100" x1="400" y2="600" x2="400" stroke-dasharray="5,5"></line> <line y1="-100" x1="500" y2="600" x2="500" stroke-dasharray="5,5"></line> </g> <!-- Figure having vector effect --> <!-- An thick red right arrow and small rectangle on this figure's nested user space origin --> <path id="ve" vector-effect="none" stroke="red" stroke-width="3" fill="none" transform="matrix(1,0,0,1,150,150)" d="M-50,-50 L50,-50 50,-100 150,0 50,100 50,50 -50,50 -50,-50z M5 0 L0 -5 -5 0 0 5z"></path> </svg> </g> </svg>
Below is an example of the non-scaling-size.
Before changing CTM | After changing CTM |
<path id="ve" vector-effect="non-scaling-size" stroke="red" stroke-width="3" fill="none" transform="matrix(1,0,0,1,150,150)" d="M-50,-50 L50,-50 50,-100 150,0 50,100 50,50 -50,50 -50,-50z M5 0 L0 -5 -5 0 0 5z"/>
Below is an example of the non-rotation.
Before changing CTM | After changing CTM |
<path id="ve" vector-effect="non-rotation" stroke="red" stroke-width="3" fill="none" transform="matrix(1,0,0,1,150,150)" d="M-50,-50 L50,-50 50,-100 150,0 50,100 50,50 -50,50 -50,-50z M5 0 L0 -5 -5 0 0 5z"/>
Below is an example of the non-scaling-size non-rotation.
Before changing CTM | After changing CTM |
<path id="ve" vector-effect="non-scaling-size non-rotation" stroke="red" stroke-width="3" fill="none" transform="matrix(1,0,0,1,150,150)" d="M-50,-50 L50,-50 50,-100 150,0 50,100 50,50 -50,50 -50,-50z M5 0 L0 -5 -5 0 0 5z"/>
Below is an example of the fixed-position.
Before changing CTM | After changing CTM |
<path id="ve" vector-effect="fixed-position" stroke="red" stroke-width="3" fill="none" transform="matrix(1,0,0,1,150,150)" d="M-50,-50 L50,-50 50,-100 150,0 50,100 50,50 -50,50 -50,-50z M5 0 L0 -5 -5 0 0 5z"/>
Below is an example of the non-scaling-size fixed-position.
Before changing CTM | After changing CTM |
<path id="ve" vector-effect="non-scaling-size fixed-position" stroke="red" stroke-width="3" fill="none" transform="matrix(1,0,0,1,150,150)" d="M-50,-50 L50,-50 50,-100 150,0 50,100 50,50 -50,50 -50,-50z M5 0 L0 -5 -5 0 0 5z"/>
Below is an example of the non-rotation fixed-position.
Before changing CTM | After changing CTM |
<path id="ve" vector-effect="non-rotation fixed-position" stroke="red" stroke-width="3" fill="none" transform="matrix(1,0,0,1,150,150)" d="M-50,-50 L50,-50 50,-100 150,0 50,100 50,50 -50,50 -50,-50z M5 0 L0 -5 -5 0 0 5z"/>
Below is an example of the non-scaling-size non-rotation fixed-position.
Before changing CTM | After changing CTM |
<path id="ve" vector-effect="non-scaling-size non-rotation fixed-position" stroke="red" stroke-width="3" fill="none" transform="matrix(1,0,0,1,150,150)" d="M-50,-50 L50,-50 50,-100 150,0 50,100 50,50 -50,50 -50,-50z M5 0 L0 -5 -5 0 0 5z"/>
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.
The ‘marker-start
’ and ‘marker-end
’ properties
can be used to place markers at the first and last vertex, and the
‘marker-mid
’ property can be used to place markers at every
other vertex (aside from the first and last). The ‘marker-start
’ and
‘marker-end
’ can be used for example to add arrowheads to paths.
Markers placed using these properties are known as
vertex markers.
In SVG 2, vertex markers are the only kind of markers available. Other specifications will extend marker functionality.
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
’ and ‘marker-mid
’ 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:
marker-start
’marker-mid
’ markers, in order of their position along the pathmarker-end
’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:
stroke-width
’ property) in
place for the graphic object referencing the marker.Name | Value | Lacuna value | Animatable |
---|---|---|---|
markerWidth, markerHeight | <length> | <percentage> | <number> | 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 | <length> | <percentage> | <number> | left | center | right | 0 | yes |
refY | <length> | <percentage> | <number> | top | center | bottom | 0 | yes |
New in SVG 2: geometric keywords (matches use in ‘symbol’).
We will add top/center/bottom, left/center/right keywords to refX/refY on marker/symbol. Resolved at London F2F. Values inspired by 'background-position'.
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 | auto-start-reverse | <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:
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.
This needs to reference a definition for how
directionality of a given start/mid/end vertex is calculated.
Part of that (which should be moved somewhere more appropriate) is in
the path element implementation notes.
Some wording from SVG 1.1 appears to have been lost, compare with this.
Here's an example that is a bit unclear currently:
<svg>
<marker id="m" orient="auto" overflow="visible">
<rect x="-1" y="-0.5" width="1" height="1" fill="green"/>
</marker>
<path d="M50,0C50,50 50,100 50,100" marker-end="url(#m)" stroke-width="100" stroke="red"/>
</svg>
The second control point and the endpoint coincide, should this mean that the direction of the endpoint is a) unknown [aka default to 0 degrees] or
b) that you have to look at the previous segment(s)/command(s) until a direction can be established?
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:
A value of 'auto-start-reverse'
means the same as 'auto' except that
for a marker placed by ‘marker-start
’, the orientation is 180°
different from the orientation as determined by 'auto'.
This allows a single arrowhead marker to be defined that can be used for both the start and end of a path, point in the right directions.
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.
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 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.
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.
A number of marker properties allow specifying a ‘marker’ using a <marker-ref> value.
where:
Values have the following meaning
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 <url> 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:
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>
Name: | marker |
---|---|
Value: | none | <marker-ref> |
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
’ and ‘marker-end
’
properties. The value of the ‘marker
’ is used
directly for all three of the corresponding longhand properties.
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:
stroke-width
’. If ‘markerUnits’ equals
'userSpaceOnUse', then no extra scale
transformation is applied.overflow
’ property on the ‘marker’ element
indicates that the marker needs to be clipped to its viewport, then an
implicit clipping path is established at the bounds of the viewport.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" 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" 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)
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. The property name is now resolved, see 15 Nov 2013 minutes. |
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.
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>
Name: | color-interpolation |
---|---|
Value: | auto | sRGB | linearRGB |
Initial: | sRGB |
Applies to: | container elements, graphics elements, gradient elements and ‘animate’ |
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:
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:
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.
Name: | color-rendering |
---|---|
Value: | auto | optimizeSpeed | optimizeQuality |
Initial: | auto |
Applies to: | container elements, graphics elements, gradient elements and ‘animate’ |
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:
‘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.
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:
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:
The CSS Image Values and Replacement Conent Module Level 4 may in the future redefine this property. In particular it should allow the choice between smoothing and keeping a pixelated look when upscaling.
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:
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.
High quality SVG viewers should perform the image processing using a linear color space.
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 |
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>
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; attribute DOMString orient; void setOrientToAuto(); void setOrientToAngle(SVGAngle angle); }; SVGMarkerElement implements SVGFitToViewBox;