This section covers Paint Servers, a method which
allows the ‘fill
’ or ‘stroke
’ of an object to be defined
by a resource found elsewhere. It allows resources to be reused
throughout a document. See the section
Painting: Filling and Stroking for a
general discussion of filling and stroking objects.
SVG defines several types of paint servers:
SVG1.1 refers to "built-in" paint servers. Is there any other kind?
SVG 2 Requirement: | Arbitrary fills for shapes. |
---|---|
Resolution: | SVG 2 shall support filling and stroking from arbitrary elements. |
Purpose: | To allow for example videos or images to be used as a fill source. |
Owner: | Alex? (no action) |
Paint servers are used by including a URL reference in
a ‘fill
’ or ‘stroke
’ property (i.e. fill="url(#MyLightPurple)").
Properties inherit into a paintserver element from its ancestors; properties do not inherit from the element referencing the paintserver element.
Paintserver elements are never rendered directly (with the exception
of ‘mesh’ which may be rendered in a non-paintserver
mode); their only usage is as something that can be referenced using
the ‘fill
’ and ‘stroke
’ properties. The
‘display
’ property does not apply to a paintserver element;
thus, paintserver elements are not directly rendered even if
the ‘display
’ property is set to a value other
than none, and paintserver elements
are available for referencing even when the ‘display
’
property on the paintserver element or any of its ancestors is set
to none.
Solid Colors are new in SVG 2 (ported from SVG 1.2 Tiny).
SVG 2 Requirement: | Support named colors. |
---|---|
Resolution: | Will add ‘solidColor’ element to SVG 2. |
Purpose: | To provide an easy mechanism for creating named colors and palettes. Also useful for animation. |
Owner: | Tav (no action) |
The 'solidcolor' element is a paint server that provides a single color with opacity. It can be referenced any place a single color can be used. The 'solidcolor' element allows a palette to be defined and used consistently throughout a document. It is also useful as away of animating a palette colors. (See CSS3 Color for a more general discussion of color [CSS3COLOR].)
Solid colors are defined by a ‘solidcolor’ element.
The ‘solid-color
’ property specifies the color of
the ‘solidcolor’. The keyword
currentColor and ICC colors
can be specified in the same manner as within a
<paint>
specification for the ‘fill
’ and ‘stroke
’
properties.
solid-color
’ elements
The ‘solid-opacity
’ property defines the opacity of
the ‘solidcolor’.
solid-color
’ elementsfill
’ or ‘stroke
’.
<?xml version="1.0" standalone="no"?> <svg xmlns="http://www.w3.org/2000/svg" version="2.0" viewBox="0 0 300 100" > <title>Example solidColor</title> <desc>Fill objects using a solidColor paint server.</desc> <defs> <solidColor id="MyLightPurple" solid-color="#a080ff" solid-opacity="0.5"/> </defs> <!-- The shapes are filled using a solidColor paint server --> <circle fill="url(#MyLightPurple)" cx="50" cy="50" r="40"/> <rect fill="url(#MyLightPurple)" x="110" y="10" width="80" height="80"/> <path fill="url(#MyLightPurple)" d="m 250 10 l 40 80 -80 0 z"/> </svg>
Gradients consist of smooth color transitions between points on a drawing surface. SVG provides for three types of gradients:
The above text and definition may need to be merged
Once a gradient is defined, a graphics element can be
filled or stroked with the gradient by setting the ‘fill
’
or ‘stroke
’ properties to reference the gradient.
Color transitions for linear and radial gradients are defined by a series of color stops along a gradient vector. A gradient normal defines how the colors in a vector are painted to the surface. For a linear gradient, the normal corresponds to lines with the same color. It is perpendicular to the vector in an untransformed gradient. When a graphics element references a gradient, conceptually the graphics element should take a copy of the gradient vector and gradient normal and treat it as part of its own geometry. Any transformations applied to the graphics element geometry also apply to the copied gradient vector and gradient normal. Any gradient transforms that are specified on the reference gradient are applied before any graphics element transformations are applied to the gradient.
Would it be better to just refer to the normal as the line where color is constant. In this case, it would be a circle for an untransformed radial gradient.
Alternative figure:
Color transitions for mesh gradients are defined by an array of color stops. The mapping of colors to the drawing surface in this case is done by geometric data located in the stops. This is discussed in detail in the mesh gradients section.
Linear gradients are defined by a ‘linearGradient’ element.
Defines the coordinate system for attributes ‘x1’, ‘y1’, ‘x2’ and ‘y2’.
If gradientUnits="userSpaceOnUse",
‘x1’, ‘y1’, ‘x2’, and ‘y2’
represent values in the coordinate system that results
from taking the current user coordinate system in place at
the time when the gradient element is referenced (i.e.,
the user coordinate system for the element referencing the
gradient element via a ‘fill
’ or ‘stroke
’
property) and then applying the transform specified by
attribute ‘gradientTransform’. Percentages
represent values relative to the current viewport.
If gradientUnits="objectBoundingBox", the user coordinate system for attributes ‘x1’, ‘y1’, ‘x2’ and ‘y2’ is established using the bounding box of the element to which the gradient is applied (see Object bounding box units) and then applying the transform specified by attribute ‘gradientTransform’. Percentages represent values relative to the bounding box for the object.
When gradientUnits="objectBoundingBox" and ‘gradientTransform’ is the identity matrix, the normal of the linear gradient is perpendicular to the gradient vector in object bounding box space (i.e., the abstract coordinate system where (0,0) is at the top/left of the object bounding box and (1,1) is at the bottom/right of the object bounding box). When the object's bounding box is not square, the gradient normal which is initially perpendicular to the gradient vector within object bounding box space may render non-perpendicular relative to the gradient vector in user space. If the gradient vector is parallel to one of the axes of the bounding box, the gradient normal will remain perpendicular. This transformation is due to application of the non-uniform scaling transformation from bounding box space to local coordinate system.
Contains the definition of an optional additional transformation from the gradient coordinate system onto the target coordinate system (i.e., 'userSpaceOnUse' or 'objectBoundingBox'). This allows for things such as skewing the gradient. This additional transformation matrix is post-multiplied to (i.e., inserted to the right of) any previously defined transformations, including the implicit transformation necessary to convert from object bounding box units to local coordinate system.
‘x1’, ‘y1’, ‘x2’ and ‘y2’ define a gradient vector for the linear gradient. This gradient vector provides starting and ending points onto which the gradient stops are mapped. The values of ‘x1’, ‘y1’, ‘x2’ and ‘y2’ can be either numbers or percentages.
See ‘x1’.
See ‘x1’.
See ‘x1’.
Indicates what happens if the gradient starts or ends inside the bounds of the target rectangle.
A URL reference to a different ‘linearGradient’ or ‘radialGradient’ element within the current SVG document fragment. Any ‘linearGradient’ attributes which are defined on the referenced element which are not defined on this element are inherited by this element. If this element has no defined gradient stops, and the referenced element does (possibly due to its own ‘href’ attribute), then this element inherits the gradient stop from the referenced element. Inheritance can be indirect to an arbitrary level; thus, if the referenced element inherits attribute or gradient stops due to its own ‘href’ attribute, then the current element can inherit those attributes or gradient stops.
Refer to the common handling defined for URL reference attributes and deprecated XLink attributes.
If ‘x1’ = ‘x2’ and ‘y1’ = ‘y2’, then the area to be painted will be painted as a single color using the color and opacity of the last gradient stop.
Example lingrad01 shows how to fill a rectangle by referencing a linear gradient paint server.
<?xml version="1.0" standalone="no"?> <svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 300 200" > <title>Example lingrag01</title> <desc>Fill a rectangle using a linear-gradient paint server.</desc> <defs> <linearGradient id="MyGradient"> <stop offset="5%" stop-color="#A8F" /> <stop offset="95%" stop-color="#FDC" /> </linearGradient> </defs> <!-- The rectangle is filled using a linear-gradient paint server --> <rect fill="url(#MyGradient)" stroke="black" stroke-width="2" x="25" y="25" width="250" height="150"/> </svg>
Radial gradients are defined by a ‘radialGradient’ element.
Defines the coordinate system for attributes ‘cx’, ‘cy’, ‘r’, ‘fx’, ‘fy’, and ‘fr’.
If gradientUnits="userSpaceOnUse",
‘cx’, ‘cy’, ‘r’, ‘fx’, ‘fy’,
and ‘fr’
represent values in the coordinate system that results
from taking the current user coordinate system in place at
the time when the gradient element is referenced (i.e.,
the user coordinate system for the element referencing the
gradient element via a ‘fill
’ or ‘stroke
’
property) and then applying the transform specified by
attribute ‘gradientTransform’. Percentages
represent values relative to the current viewport.
If gradientUnits="objectBoundingBox", the user coordinate system for attributes ‘cx’, ‘cy’, ‘r’, ‘fx’, ‘fr’, and ‘fr’ is established using the bounding box of the element to which the gradient is applied (see Object bounding box units) and then applying the transform specified by attribute ‘gradientTransform’. Percentages represent values relative to the bounding box for the object.
When gradientUnits="objectBoundingBox" and ‘gradientTransform’ is the identity matrix, then the rings of the radial gradient are circular with respect to the object bounding box space (i.e., the abstract coordinate system where (0,0) is at the top/left of the object bounding box and (1,1) is at the bottom/right of the object bounding box). When the object's bounding box is not square, the rings that are conceptually circular within object bounding box space will render as elliptical due to application of the non-uniform scaling transformation from bounding box space to local coordinate system.
Contains the definition of an optional additional transformation from the gradient coordinate system onto the target coordinate system (i.e., 'userSpaceOnUse' or 'objectBoundingBox'). This allows for things such as skewing the gradient. This additional transformation matrix is post-multiplied to (i.e., inserted to the right of) any previously defined transformations, including the implicit transformation necessary to convert from object bounding box units to local coordinate system.
‘cx’, ‘cy’ and ‘r’ define the end circle for the radial gradient. The gradient will be drawn such that the 100% gradient stop is mapped to the perimeter of this end circle.
See ‘cx’.
See ‘cx’.
A negative value is an error (see Error processing).
‘fx’, ‘fy’, and ‘fr’ define the start circle for the radial gradient. The gradient will be drawn such that the 0% gradient stop is mapped to the perimeter of this start circle.
If attribute ‘fx’ is not specified, ‘fx’ will coincide with the presentational value of ‘cx’ for the element whether the value for 'cx' was inherited or not. If the element references an element that specifies a value for 'fx', then the value of 'fx' is inherited from the referenced element.
See ‘fx’.
If attribute ‘fy’ is not specified, ‘fy’ will coincide with the presentational value of ‘cy’ for the element whether the value for 'cy' was inherited or not. If the element references an element that specifies a value for 'fy', then the value of 'fy' is inherited from the referenced element.
New in SVG 2. Added to align with Canvas.
‘fr’ is the radius of the focal circle. See ‘fx’.
A negative value is an error (see Error processing).
If the attribute is not specified, the effect is as if a value of '0%' were specified. If the element references an element that specifies a value for 'fr', then the value of 'fr' is inherited from the referenced element.
SVG 2 Requirement: | Allow specifying focal circle radius in radial gradients. |
---|---|
Resolution: | Add an ‘fr’ attribute to ‘radialGradient’> for SVG 2. |
Purpose: | To align with Canvas. The zero-offset stop would be along the circle defined by the ‘fx’, ‘fy’ and ‘fr’ attributes. |
Owner: | Erik (ACTION-3098) |
Indicates what happens if the gradient starts or ends inside the bounds of the object(s) being painted by the gradient. Has the same values and meanings as the ‘spreadMethod’ attribute on ‘linearGradient’ element.
A URL reference to a different ‘linearGradient’ or ‘radialGradient’ element within the current SVG document fragment. Any ‘radialGradient’ attributes which are defined on the referenced element which are not defined on this element are inherited by this element. If this element has no defined gradient stops, and the referenced element does (possibly due to its own ‘href’ attribute), then this element inherits the gradient stop from the referenced element. Inheritance can be indirect to an arbitrary level; thus, if the referenced element inherits attribute or gradient stops due to its own ‘href’ attribute, then the current element can inherit those attributes or gradient stops.
Refer to the common handling defined for URL reference attributes and deprecated XLink attributes.
SVG 2 Requirement: | Clarify radial gradients with focal point on the circle. |
---|---|
Resolution: | When the focal point is on the circle edge, with repeat, then the distance between the first and last stop for the repeating colors is 0 and the paint should generate a color that is the average of all the gradient stops. |
Purpose: | To improve interoperability of radial gradients. |
Owner: | Erik (ACTION-3097) |
Note: | SVG 1.1 does not define what to do when the focal point is on the circle edge, with 'repeat'. The distance between the first and last stop for the repeating colors is 0. It was resolved that the paint should generate a color that is the weighted average (by offset) of all the gradient stops. |
Changed in SVG 2. SVG 1.1 required that the focal point, if outside the end circle, be moved to be on the end circle. The change was made to align with Canvas.
Allowing the focal point to lie outside the end circle was resolved at the Rigi Kaltbad working group meeting.
If the start circle defined by ‘fx’, ‘fy’ and ‘fr’ lies outside the end circle defined by ‘cx’, ‘cy’, and ‘r’, effectively a cone is created, touched by the two circles. Areas outside the cone stay untouched by the gradient (transparent black).
If the start circle fully overlaps with the end circle, no gradient is drawn. The area stays untouched (transparent black).
The treatment of the area to the right of the gradient in the right-hand side of the above figure is different from that of Canvas where the area would be transparent black. The difference is to maintain compatibility with SVG 1.1.
The color space for the weighted average is the same as in which the gradient is interpolated. See Rigi Kaltbad working group meeting.
Example radgrad01 shows how to fill a rectangle by referencing a radial gradient paint server.
<?xml version="1.0" standalone="no"?> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 300 200" > <title>Example radgrad01</title> <desc>Fill a rectangle by referencing a radial gradient paint server.</desc> <defs> <radialGradient id="MyGradient" gradientUnits="userSpaceOnUse" cx="150" cy="100" r="100"> <stop offset="0%" stop-color="#A8F" /> <stop offset="50%" stop-color="#FDC" /> <stop offset="100%" stop-color="#A8F" /> </radialGradient> </defs> <!-- The rectangle is filled using a radial gradient paint server --> <rect fill="url(#MyGradient)" stroke="black" stroke-width="2" x="25" y="25" width="250" height="150"/> </svg>
SVG 2 Requirement: | Support photorealistic gradients. |
---|---|
Resolution: | Mesh gradients are accepted by the WG for SVG 2. |
Purpose: | To allow more complex gradients such as those found in nature. |
Owner: | Tav (ACTION-3121) |
Resolution: Rename stop-path to 'd' or 'path' (Coons patch syntax).
Resolution: We will allow just C/c/L/l in mesh path data. We will leave out tensor control points. We will not allow multiple colors at mesh intersections, just use zero size patches instead.
Resolution: We will have a type="smooth-bicubic" or similar on <mesh>. (Note: In the resolution, the attribute is incorrectly placed on <patch>; see the minutes.)
New in SVG 2. Added to allow complex shadings. This is needed, for example, in creating life-like drawings or in interpolating data points on a two-dimensional grid.
The mesh gradients in SVG are based on an array of Coons Patches. A Coons Patch is a shading defined by colors place at the corners of an area enclosed by four Bézier curves. The interpolation of the corner colors into the patch can either be bilinear or bicubic.
A Coons Patch is equivalent to a bi-cubic Ferguson patch where the distance between a cubic Bézier end point and its nearest control point is one-third the length of the corresponding Ferguson tangent line.
Unlike other paint servers, a mesh defined outside of a ‘defs’ section is rendered. In this the case, the mesh has a bounding box determined by its maximum extent, taking into account all of its patches.
A mesh consists of patches placed in an array. There are two reasons for using an array. The first is that an array of meshes is a natural result for most content creation processes (start with a path and then subdivide its area into rows and columns of patches). The second is that the data can be compacted by sharing sides and corners. The array structure is conceptual only. The actual mesh can be distorted in any way possible. The mesh gradient syntax is designed so that it is easy to simulate other types of gradients such as conical gradients or triangle meshes as shown in the examples below.
The structure of a mesh gradient:
<mesh x="100" y="100"> <meshrow> <meshpatch> <stop .../> Up to four stops in first patch. See details below. </meshpatch> <meshpatch> Any number of meshpatches in row. </meshpatch> </meshrow> <meshrow> Any number of meshrows, each with the same number of meshpatches as in the first row. </meshrow> </mesh>
The first ‘meshpatch’ in the first ‘meshrow’ contains four ‘stop’ elements. These elements correspond conceptually, in order, to the top, right, bottom, and left edges of the first patch. The following patches in the first row contains three ‘stop’ elements, corresponding to the top, right, and bottom edges of the patch. The left edge of one of these patches is taken from the (reversed) right edge of the previous patch. The first patch of following rows contains three ‘stop’ elements, corresponding to the right, bottom, and left edges. The top edge is taken from the (reversed) bottom edge of the first patch in the row above. The remaining patches contain two ‘stop’ elements, corresponding to the right and bottom edges of the patch. The top edge is taken from the patch directly above in the array of patches while the left edge is taken from the previous patch in the same row.
Each ‘stop’ element contains a ‘path’ attribute which consists of a single 'c', 'C', 'l', or 'L' path command. The initial point for the path command is taken from the last point of the previous edge of the patch (which for the first ‘stop’ in a patch is defined in the patch to the left or top), except for the first patch in the first row where the initial point is given by the ‘x’ and ‘y’ attributes in the ‘mesh’ element. The path command in the last ‘stop’ element of a ‘meshpatch’ has one less point than normal as this "missing" point necessary to close the path is already defined.
For each ‘stop’ element there is a color and opacity
that correspond to the patch corner at the initial point of
the stop's edge. This color and opacity are defined inside
the ‘stop’ by the ‘stop-color
’
and ‘stop-opacity
’ properties except for the first
stop in all patches other than the first patch in the first
row where the stop color and opacity are already defined by a
previous patch.
Here is an annotated example of a two by two mesh:
<mesh x="50" y="50" id="example"> <!-- x, y used for initial point in first patch. --> <meshrow> <!-- No attributes, used only to define begin/end of row. --> <meshpatch> <stop path="c 25,-25 75, 25 100,0" stop-color="lightblue" /> <stop path="c 25, 25 -25, 75 0,100" stop-color="purple" /> <stop path="c -25, 25 -75,-25 -100,0" stop-color="red" /> <stop path="c -25,-25, 25,-75" stop-color="purple" /> <!-- Last point not needed (closed path). --> </meshpatch> <meshpatch> <stop path="c 25,-25 75, 25 100,0" /> <!-- stop-color from previous patch. --> <stop path="c 25, 25 -25, 75 0,100" stop-color="lightblue" /> <stop path="c -25, 25 -75,-25" stop-color="purple" /> <!-- Last point not needed (closed path). --> <!-- Last path (left side) taken from right side of previous path (with points reversed). --> </meshpatch> </meshrow> <meshrow> <!-- New row. --> <meshpatch> <!-- First path (top side) taken from bottom path of patch above. --> <stop path="c 25, 25 -25, 75 0,100" /> <!-- stop-color from patch above. --> <stop path="c -25, 25 -75,-25 -100,0" stop-color="purple" /> <stop path="c -25,-25, 25,-75" stop-color="lightblue" /> <!-- Last point not needed (closed path). --> </meshpatch> <meshpatch> <!-- First path (top side) taken from bottom path of patch above (with points reversed). --> <stop path="c 25, 25 -25, 75 0,100" /> <!-- stop-color from patch above. --> <stop path="c -25, 25 -75,-25" stop-color="lightblue" /> <!-- Last point not needed (closed path). --> <!-- Last path (left side) taken from right side of previous path (with points reversed). --> </meshpatch> </meshrow> </mesh>
The above mesh is rendered as:
Coons patch meshes can simulate other types of gradients. Here is an example of a conic gradient:
The corner colors are mapped to the patch area with a two step process. First the colors are placed at the corners of a unit square and the area inside the square is then colored using either bilinear interpolation or bicubic interpolation. Second, the points inside the square are mapped to points inside the patch using the following formula:
$S = S_C + S_D - S_B$
where
$$ \begin{align} S_C(u,v) &= (1-v)×C_1(u) + v×C_2(u),\\ S_D(u,v) &= (1-u)×D_1(v) + u×D_2(v),\\ S_B(u,v) &= (1-v)×[(1-u)×C_1(0) + u×C_1(1)]\\ &\qquad {}+ v×[(1-u)×C_2(0) + u×C_2(1)]. \end{align} $$
, , , and are the curves at the top, bottom, left, and right of the patch, respectively; and are the coordinates inside the unit square. The subtraction term ensures that the boundary conditions are met.
Come up with better explanation of the mapping with diagram.
One method of rendering a patch is to "divide and conquer." Check if the four corner colors of the patch are the same within a specified tolerance. If so, paint the patch with the average color using the normal path filling routine. If not, divide the patch into four smaller patches and repeat the color tolerance check. Repeat the process as many times as necessary.
Another way to render a patch is to first divide the patch vertically or horizontally into a series of smaller patches that are each less than one pixel high or wide. Then each resulting patch can be rendered as a path.
Bilinear interpolation of the corner colors depends only on the values of the corner colors. The color profile along two opposite edges is first computed and then corresponding points along those edges are interpolated to fill in the interior. The color profile across a patch boundary may not be smooth, leading to an optical phenomena known as Mach banding.
Bicubic interpolation requires knowing not only the value of the corner colors but also their derivatives. The derivatives are chosen to ensure a smooth transition across patch boundaries and that there are no color value minima or maxima in the patch interior (i.e. a monotone cubic interpolation). Only the derivatives in x and y (where the x and y are the directions along the rows and columns of the conceptual mesh grid) are used (the cross derivatives are set to zero).
To calculate the derivatives: Let be the color value at the point , where .
\Delta_k = {{c_{k+1}-c_k}\over{\lvert p_{k+1}-p_k\rvert}}
$ \delta_k = {\Delta_{k-1} + \Delta_k\over 2} $
$ \delta_1 = 2\times\Delta_1 - \delta_2 $
$ \delta_n = 2\times\Delta_{n-1} - \delta_{n-1} $
The typical method for dealing with the start or end of a bicubic interpolation is to add an extra point before and an extra point after the given points. The value of the point before (after) is assigned either the value of the first (last) point or a value so that the secant before (after) is the same as the secant after (before) the first (last) point. The method described here does not rely on the addition of points but instead fits a quadratic curve to the color values and the already determined derivative at the other edge of the patch. This produces an interpolation that does not have an inflection point inside the patch.
Bicubic interpolation will produce smooth patch boundaries when a mesh is laid out on a rectangular grid and where the patch edges are linear. If the grid is distorted or the patch edges are not lines (i.e. they are Bézier curves), it is still possible to produce non-smooth transitions across patch boundaries.
Mesh gradients are defined by a ‘mesh’ element.
Defines the coordinate system for attributes ‘x’ and ‘y’.
If gradientUnits="userSpaceOnUse",
‘x’ and ‘y’
represent values in the coordinate system that results
from taking the current user coordinate system in place at
the time when the gradient element is referenced (i.e.,
the user coordinate system for the element referencing the
gradient element via a ‘fill
’ or ‘stroke
’
property) or when the mesh is rendered on its own
(i.e. not as a paint server) and then applying the
transform specified by attribute
‘transform’. Percentages represent values
relative to the current viewport.
If gradientUnits="objectBoundingBox", the user coordinate system for attributes ‘x’ and ‘y’, is established using the bounding box of the element to which the gradient is applied (see Object bounding box units) and then applying the transform specified by attribute ‘transform’. Percentages represent values relative to the bounding box for the object.
When a mesh is rendered on its own (i.e. not as a paint server) this value is not valid and the current user coordinate system is used.
Contains the definition of an optional additional transformation from the mesh coordinate system onto the target coordinate system (i.e., 'userSpaceOnUse'). This allows for things such as skewing the gradient. This additional transformation matrix is post-multiplied to (i.e., inserted to the right of) any previously defined transformations.
‘x’ and ‘y’ define the starting point of the mesh grid.
See ‘x’.
A URL reference to a different ‘mesh’ element within the current SVG document fragment. Any ‘mesh’ attributes which are defined on the referenced element which are not defined on this element are inherited by this element. Inheritance can be indirect to an arbitrary level; thus, if the referenced element inherits attribute due to its own ‘href’ attribute, then the current element can inherit those attributes.
Refer to the common handling defined for URL reference attributes and deprecated XLink attributes.
Determines the type of interpolation to use when painting a patch.
Mesh rows are defined by a ‘meshrow’ element.
Mesh patches are defined by a ‘meshpatch’ element.
The vector (linear and radial gradients) or array (mesh gradients) of colors to use in a gradient is defined by the ‘stop’ elements that are child elements to a ‘linearGradient’, ‘radialGradient’, or ‘meshpatch’ element.
In SVG 1.1, the above read: "The ramp of colors..." but "ramp" is used nowhere else in this section.
Indicates were the gradient stop is placed. For linear gradients, the ‘offset’ attribute represents a location along the gradient vector. For radial gradients, it represents a fractional distance from the edge of the innermost/smallest circle to the edge of the outermost/largest circle. This attribute does not apply to mesh gradients.
Gives the path for one side of a mesh gradient patch. This attribute applies only to mesh gradients.
Mesh path data consists of a single 'l', 'L', 'c', or 'C' path command (as defined for the Path ‘d’ attribute). See the ‘mesh’ section above for how the path data is interpreted.
The ‘stop-color
’ property indicates what color to use
at that gradient stop. The keyword
currentColor and ICC colors
can be specified in the same manner as within a
<paint>
specification for the ‘fill
’ and ‘stroke
’
properties.
The ‘stop-opacity
’ property defines the opacity of
a given gradient stop.
fill
’ or ‘stroke
’.
If two gradient stops have the same offset value, then the latter gradient stop controls the color value at the overlap point. In particular:
<stop offset="0" stop-color="white"/> <stop offset=".2" stop-color="red"/> <stop offset=".2" stop-color="blue"/> <stop offset="1" stop-color="black"/>
will have approximately the same effect as:
<stop offset="0" stop-color="white"/> <stop offset=".1999999999" stop-color="red"/> <stop offset=".2" stop-color="blue"/> <stop offset="1" stop-color="black"/>
which is a gradient that goes smoothly from white to red, then abruptly shifts from red to blue, and then goes smoothly from blue to black.
A pattern is used to ‘fill
’ or ‘stroke
’
an object using a pre-defined graphic object which can be replicated
("tiled") at fixed intervals in x and y to cover the
areas to be painted. Patterns are defined using a ‘pattern’
element and then referenced by properties ‘fill
’ and
‘stroke
’ on a given graphics element to indicate that the
given element shall be filled or stroked with the pattern.
Attributes ‘x’, ‘y’, ‘width’, ‘height’ and ‘patternUnits’ define a reference rectangle somewhere on the infinite canvas. The reference rectangle has its top/left at (x, y) and its bottom/right at (x + width, y + height). The tiling theoretically extends a series of such rectangles to infinity in X and Y (positive and negative), with rectangles starting at (x + m*width, y + n* height) for each possible integer value for m and n.
Defines the coordinate system for attributes ‘x’, ‘y’, ‘width’ and ‘height’.
If patternUnits="userSpaceOnUse",
‘x’, ‘y’, ‘width’ and ‘height’
represent values in the coordinate system that results
from taking the current user coordinate system in place at
the time when the ‘pattern’ element is referenced
(i.e., the user coordinate system for the element
referencing the ‘pattern’ element via a
‘fill
’ or ‘stroke
’ property) and then
applying the transform specified by attribute
‘patternTransform’. Percentages
represent values relative to the current viewport.
If patternUnits="objectBoundingBox", the user coordinate system for attributes ‘x’, ‘y’, ‘width’ and ‘height’ is established using the bounding box of the element to which the pattern is applied (see Object bounding box units) and then applying the transform specified by attribute ‘patternTransform’. Percentages represent values relative to the bounding box for the object.
Defines the coordinate system for the contents of the ‘pattern’. Note that this attribute has no effect if attribute ‘viewBox’ is specified.
If patternContentUnits="userSpaceOnUse",
the user coordinate system for the contents of the ‘pattern’
element is the coordinate system that results from taking
the current user coordinate system in place at the time
when the ‘pattern’ element is referenced (i.e., the
user coordinate system for the element referencing the
‘pattern’ element via a ‘fill
’ or ‘stroke
’
property) and then applying the transform specified by attribute
‘patternTransform’.
If patternContentUnits="objectBoundingBox", the user coordinate system for the contents of the ‘pattern’ element is established using the bounding box of the element to which the pattern is applied (see Object bounding box units) and then applying the transform specified by attribute ‘patternTransform’.
Contains the definition of an optional additional transformation from the pattern coordinate system onto the target coordinate system (i.e., 'userSpaceOnUse' or 'objectBoundingBox'). This allows for things such as skewing the pattern tiles. This additional transformation matrix is post-multiplied to (i.e., inserted to the right of) any previously defined transformations, including the implicit transformation necessary to convert from object bounding box units to local coordinate system.
‘x’, ‘y’, ‘width’ and ‘height’ indicate how the pattern tiles are placed and spaced. These attributes represent coordinates and values in the coordinate space specified by the combination of attributes ‘patternUnits’ and ‘patternTransform’.
See ‘x’.
See ‘x’.
A negative value is an error (see Error processing). A value of zero disables rendering of the element (i.e., no paint is applied).
See ‘x’.
A negative value is an error (see Error processing). A value of zero disables rendering of the element (i.e., no paint is applied).
A URL reference to a different ‘pattern’ element within the current SVG document fragment. Any attributes which are defined on the referenced element which are not defined on this element are inherited by this element. If this element has no children, and the referenced element does (possibly due to its own ‘href’ attribute), then this element inherits the children from the referenced element. Inheritance can be indirect to an arbitrary level; thus, if the referenced element inherits attributes or children due to its own ‘href’ attribute, then the current element can inherit those attributes or children.
Refer to the common handling defined for URL reference attributes and deprecated XLink attributes.
See ‘preserveAspectRatio’.
SVG's user agent style sheet sets
the ‘overflow
’ property for ‘pattern’ elements to
hidden, which causes a rectangular clipping
path to be created at the bounds of the pattern tile. Unless the
‘overflow
’ property is overridden, any graphics within the pattern
which goes outside of the pattern rectangle will be clipped. Note that if
the ‘overflow
’ property is set to visible
the rendering behavior for the pattern is undefined.
Example pattern01 below shows the
effect of clipping to the pattern tile.
The contents of the ‘pattern’ are relative to a new coordinate system. If there is a ‘viewBox’ attribute, then the new coordinate system is fitted into the region defined by the ‘x’, ‘y’, ‘width’, ‘height’ and ‘patternUnits’ attributes on the ‘pattern’ element using the standard rules for ‘viewBox’ and ‘preserveAspectRatio’. If there is no ‘viewBox’ attribute, then the new coordinate system has its origin at (x, y), where x is established by the ‘x’ attribute on the ‘pattern’ element, and y is established by the ‘y’ attribute on the ‘pattern’ element. Thus, in the following example:
<pattern x="10" y="10" width="20" height="20"> <rect x="5" y="5" width="10" height="10"/> </pattern>
the rectangle has its top/left located 5 units to the right and 5 units down from the origin of the pattern tile.
The ‘viewBox’ attribute introduces a supplemental transformation which is applied on top of any transformations necessary to create a new pattern coordinate system due to attributes ‘x’, ‘y’, ‘width’, ‘height’ and ‘patternUnits’.
Event attributes and event listeners attached to the contents of a ‘pattern’ element are not processed; only the rendering aspects of ‘pattern’ elements are processed.
Example pattern01
shows how to fill a rectangle by referencing a pattern paint
server. Note how the blue stroke of each triangle has been
slightly clipped at the top and the left. This is due to SVG's
user agent style sheet setting
the ‘overflow
’ property for ‘pattern’ elements to
hidden, which causes the pattern to be clipped
to the bounds of the pattern tile.
<?xml version="1.0" standalone="no"?> <svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 300 200" > <title>Example pattern01</title> <desc>Fill an ellipse using a pattern paint server.</desc> <defs> <pattern id="TrianglePattern" patternUnits="userSpaceOnUse" x="0" y="0" width="50" height="50" viewBox="0 0 10 10" > <path d="M 0 0 L 7 0 L 3.5 7 z" fill="plum" stroke="blue" /> </pattern> </defs> <!-- The ellipse is filled using a triangle pattern paint server --> <ellipse fill="url(#TrianglePattern)" stroke="black" stroke-width="2" cx="150" cy="100" rx="125" ry="75" /> </svg>
Hatches are new in SVG 2. They were added to allow the kinds of patterns required for mapping, engraving, etc. where continuous lines are needed.
SVG 2 Requirement: | Support hatches. |
---|---|
Resolution: | SVG 2 should support hatchings without the artifacts that patterns currently impose. |
Purpose: | To allow the kinds of patterns required for mapping, engraving, etc. where continuous lines are required. |
Owner: | Tav (no action) |
A hatch is used to ‘fill
’ or ‘stroke
’
an object using one or more pre-defined paths that are repeated
at fixed intervals in a specified direction to cover the
areas to be painted. Hatches are defined using a ‘hatch’
element and then referenced by properties ‘fill
’ and
‘stroke
’ on a given graphics element to indicate that the
given element shall be filled or stroked with the hatch.
Paths are defined by ‘hatchpath’ elements.
Attributes ‘x’, ‘y’, ‘pitch’, ‘rotate’, and ‘hatchUnits’ define an infinitely long reference strip on the infinite canvas. The strip has one edge at (x, y) and its other edge at a distance of pitch in the direction defined by rotate. This one-dimension tiling theoretically extends a series of such strips in the direction of 'rotate' to infinity (positive and negative), with strips starting at (x + m*pitch*cos(rotate), y + m*pitch*sin(rotate) for each possible integer value of m.
Defines the coordinate system for attributes ‘x’, ‘y’, ‘pitch’ and ‘rotate’.
If hatchUnits="userSpaceOnUse",
‘x’, ‘y’, ‘pitch’, and ‘rotate’
represent values in the coordinate system that results
from taking the current user coordinate system in place at
the time when the ‘hatch’ element is referenced
(i.e., the user coordinate system for the element
referencing the ‘hatch’ element via a
‘fill
’ or ‘stroke
’ property) and then
applying the transform specified by attribute
‘transform’. Percentages
represent values relative to the current viewport.
If hatchUnits="objectBoundingBox", the user coordinate system for attributes ‘x’, ‘y’, ‘pitch’, and ‘rotate’ is established using the bounding box of the element to which the hatch is applied (see Object bounding box units) and then applying the transform specified by attribute ‘transform’. Percentages represent values relative to the bounding box for the object.
Defines the coordinate system for the contents of the ‘hatch’.
If hatchContentUnits="userSpaceOnUse",
the user coordinate system for the contents of the ‘hatch’
element is the coordinate system that results from taking
the current user coordinate system in place at the time
when the ‘hatch’ element is referenced (i.e., the
user coordinate system for the element referencing the
‘hatch’ element via a ‘fill
’ or ‘stroke
’
property) and then applying the transform specified by attribute
‘transform’.
If hatchContentUnits="objectBoundingBox", the user coordinate system for the contents of the ‘hatch’ element is established using the bounding box of the element to which the hatch is applied (see Object bounding box units) and then applying the transform specified by attribute ‘transform’.
Contains the definition of an optional additional transformation from the hatch coordinate system onto the target coordinate system (i.e., 'userSpaceOnUse' or 'objectBoundingBox'). This allows for things such as skewing the hatch strips. This additional transformation matrix is post-multiplied to (i.e., inserted to the right of) any previously defined transformations, including the implicit transformation necessary to convert from object bounding box units to local coordinate system.
‘x’, ‘y’, ‘pitch’ and ‘rotate’ indicate how the hatch strips are placed and spaced. These attributes represent coordinates and values in the coordinate space specified by the combination of attributes ‘hatchUnits’ and ‘transform’.
See ‘x’.
See ‘x’.
A negative value is an error (see Error processing). A value of zero disables rendering of the element (i.e., no paint is applied).
See ‘x’.
Changed name from 'angle' to 'rotate' at Tokyo F2F.
A URL reference to a different ‘hatch’ element within the current SVG document fragment. Any attributes which are defined on the referenced element which are not defined on this element are inherited by this element. If this element has no children, and the referenced element does (possibly due to its own ‘href’ attribute), then this element inherits the children from the referenced element. Inheritance can be indirect to an arbitrary level; thus, if the referenced element inherits attributes or children due to its own ‘href’ attribute, then the current element can inherit those attributes or children.
Refer to the common handling defined for URL reference attributes.
SVG's user agent style sheet sets
the ‘overflow
’ property for ‘hatch’ elements to
hidden, which causes an infinite strip clipping
path to be created at the bounds of the hatch strip. Unless the
‘overflow
’ property is overridden, any graphics within the
hatch which goes outside of the hatch strip will be clipped. Note that
if the ‘overflow
’ property is set
to visible the area outside must be
rendered (NB this is different from a ‘pattern’
element). Strips with higher x (larger m) values
must be rendered after strips with lower x
(lower m) values.
The contents of the ‘hatch’ are relative to a new coordinate system. The new coordinate system has its origin at (x, y), where x is established by the ‘x’ attribute on the ‘hatch’ element, and y is established by the ‘y’ attribute on the ‘hatch’ element. The coordinate system is rotated around the origin by the angle given by the ‘rotate’ attribute.
The viewBox and preserveAspectRatio attributes are not useful and have been removed (as compared to the pattern element).
Event listeners attached to the contents of a ‘hatch’ element are not processed; only the rendering aspects of ‘hatch’ elements are processed.
The following illustrates a very simple ‘hatch’ fill:
<hatch pitch="5" rotate="135"> <hatchpath stroke="#a080ff" stroke-width="2"/> </hatch>
Proper examples with links to the SVG need to be given.
Hatch paths are defined by a ‘hatchpath’ element.
Defines a single path in the ‘hatch’.
Defines the point along the reference line where a path begins.
Hatch paths are defined with the same Path data used in the ‘d’ attribute of the ‘path’ element. The path is defined relative to the origin of each strip translated in the x direction by the ‘offset’ (the y direction is aligned along the infinite axis of the strip).
If a ‘d’ attribute is not provided, the path defaults to an infinitely long line aligned with the y-axis of the reference strip and passing through a point ‘offset’ distance in the x direction from the strip origin (see above).
If a ‘d’ attribute is given, the hatch path is constructed
by repeating the ‘d’ data, each time with an offset along the
y-axis determined by the y value of the last
path data point. (The offset must be positive, a negative or zero
offset value results in the hatch path not being rendered.) A hatch
path need not start with a "moveto" path instruction. If missing, the
first path instruction uses for its current point a value of
(x,0) where x is the x
value of the last data point given in the path. If the first path
command is not a "moveto" and the last not a "closepath", the last
point of each repeating section is joined to the first point of the
next repeating section with the current value
of ‘stroke-linejoin
’.
A hatch path can have any of the stroke style properties applied to it, however only
solid color paint servers are allowed for the ‘stroke
’ property.
Limiting 'stroke' to solid paint servers was resolved at the Tokyo F2F.
<hatch hatchUnits="userSpaceOnUse" pitch="6"> <hatchpath stroke-width="1" d="c 0,4 8,6 8,10 8,14 0,16 0,20"/> </hatch>
<hatch hatchUnits="userSpaceOnUse" pitch="20"> <hatchpath stroke-width="2" d="L 0,0 10,50"/> </hatch>
<hatch hatchUnits="userSpaceOnUse" pitch="20"> <hatchpath stroke-width="2" d="M 0,0 10,50"/> </hatch>
<hatch hatchUnits="userSpaceOnUse" pitch="20"> <hatchpath stroke-width="2"/> <hatchpath stroke-width="2" offset="5" stroke-dasharray="10 4 2 4"/> </hatch>
IDL needs to be added for SVGSolidcolorElement.
interface SVGGradientElement : SVGElement { // Spread Method Types const unsigned short SVG_SPREADMETHOD_UNKNOWN = 0; const unsigned short SVG_SPREADMETHOD_PAD = 1; const unsigned short SVG_SPREADMETHOD_REFLECT = 2; const unsigned short SVG_SPREADMETHOD_REPEAT = 3; readonly attribute SVGAnimatedEnumeration gradientUnits; readonly attribute SVGAnimatedTransformList gradientTransform; readonly attribute SVGAnimatedEnumeration spreadMethod; }; SVGGradientElement implements SVGURIReference; SVGGradientElement implements SVGUnitTypes;
interface SVGLinearGradientElement : SVGGradientElement { readonly attribute SVGAnimatedLength x1; readonly attribute SVGAnimatedLength y1; readonly attribute SVGAnimatedLength x2; readonly attribute SVGAnimatedLength y2; };
interface SVGRadialGradientElement : SVGGradientElement { readonly attribute SVGAnimatedLength cx; readonly attribute SVGAnimatedLength cy; readonly attribute SVGAnimatedLength r; readonly attribute SVGAnimatedLength fx; readonly attribute SVGAnimatedLength fy; readonly attribute SVGAnimatedLength fr; };
interface SVGMeshElement : SVGGradientElement { readonly attribute SVGAnimatedLength x; readonly attribute SVGAnimatedLength y; };
interface SVGMeshrowElement : SVGElement { };
interface SVGMeshpatchElement : SVGElement { };
interface SVGStopElement : SVGElement { readonly attribute SVGAnimatedNumber offset; };
interface SVGPatternElement : SVGElement { readonly attribute SVGAnimatedEnumeration patternUnits; readonly attribute SVGAnimatedEnumeration patternContentUnits; readonly attribute SVGAnimatedTransformList patternTransform; readonly attribute SVGAnimatedLength x; readonly attribute SVGAnimatedLength y; readonly attribute SVGAnimatedLength width; readonly attribute SVGAnimatedLength height; }; SVGPatternElement implements SVGFitToViewBox; SVGPatternElement implements SVGURIReference; SVGPatternElement implements SVGUnitTypes;
IDL needs to be added for SVGHatchElement.