SVG Tiny 1.2 – 20081222

- Top
- Contents
- Previous
- Next
- Elements
- Attributes

# 11 Painting: Filling, Stroking, Colors and Paint Servers

## Contents

## 11.1 Introduction

Graphics elements, including text content elements and shapes, can be filled (which means painting the interior of the object) and stroked (which means painting along the outline of the object). Filling and stroking both can be thought of in more general terms as painting operations.

With SVG, you can paint (i.e., fill or stroke) with:

- a single color, possibly with some level of transparency
- a gradient (linear or radial)

SVG uses the general notion of a paint server. Apart from system paint, paint servers are specified using a local IRI reference on a 'fill' or 'stroke' property. Gradients and colors are just specific types of paint servers.

## 11.2 Specifying paint

Properties 'fill' and 'stroke' take on a value of type <paint>, which is specified as follows:

<paint>: | none | currentColor | <color> | <FuncIRI> [ none | currentColor | <color>] | <system paint> | inherit

none
  Indicates that no paint shall be applied.
currentColor
  Indicates that painting shall be done using the color specified by the current animated value of the 'color' property. This mechanism is provided to facilitate sharing of color attributes between parent grammars such as other (non-SVG) XML. This mechanism allows you to define a style in your HTML which sets the 'color' property and then pass that style to the SVG user agent so that your SVG text will draw in the same color.
<color>
  the explicit color (in the sRGB color space [SRGB]).
<FuncIRI> [ none | currentColor | <color>]
  The <FuncIRI> specifies a paint server such as a gradient. The fragment identifier of the <FuncIRI> provides a link to the paint server (e.g., a gradient or 'solidColor') that shall be used to paint the current object. SVG Tiny 1.2 user agents are only required to support local IRI references. If the IRI reference is invalid (for example, it points to an object that doesn't exist or the object is not a valid paint server or it is a non-local IRI reference and the viewer does not support it), then the fallback value (if specified) is used; otherwise it must be treated as if none was specified.
<system paint>
  A system paint server

## 11.3 Fill properties

'fill'

  Value: | <paint> | inherit (See Specifying paint)
  Initial: | black
  Applies to: | shapes and text content elements
  Inherited: | yes
  Percentages: | N/A
  Media: | visual
  Animatable: | yes
  Computed value: | "none", system paint, specified <color> value or absolute IRI

The 'fill' property specifies that the interior of the given graphical element must be painted. The area to be painted shall consist of any areas inside the outline of the shape. To determine the inside of the shape, all subpaths must be considered, and the interior shall be determined according to the rules associated with the current value of the 'fill-rule' property. The zero-width geometric outline of a shape must be included in the area to be painted.

Open subpaths must be filled 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.

'fill-rule'

  Value: | nonzero | evenodd | inherit
  Initial: | nonzero
  Applies to: | shapes and text content elements
  Inherited: | yes
  Percentages: | N/A
  Media: | visual
  Animatable: | yes
  Computed value: | Specified value, except inherit

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

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

nonzero
  The following algorithm, or any other that gives the same result, must be used to determine the "insideness" of a point on the canvas. Draw a ray from the point to infinity in any direction and then examine 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:

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

evenodd
  The following algorithm, or any other that gives the same result, must be used to determine the "insideness" of a point on the canvas. Draw a ray from the 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:

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

(Note: the above explanations 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.)

'fill-opacity'

  Value: | <opacity-value> | inherit
  Initial: | 1
  Applies to: | shapes and text content elements
  Inherited: | yes
  Percentages: | N/A
  Media: | visual
  Animatable: | yes
  Computed value: | Specified value, except inherit

'fill-opacity' specifies the opacity of the painting operation which shall be used to paint the interior the current object. (See Painting shapes and text.)

<opacity-value>
  The opacity of the painting operation that is to be used to fill the current object. Any values outside the range 0.0 (fully transparent) to 1.0 (fully opaque) must be clamped to this range. (See Clamping values which are restricted to a particular range.)

Related property: 'stroke-opacity'.

## 11.4 Stroke properties

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

In all cases, strokes which are affected by directionality, such as those having 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 strokes, such as dash patterns whose computations are dependent on progress along the outline of the graphics element, distance calculations must use the SVG user agent's standard distance along a path algorithms.

When stroking is performed using a complex paint server, such as a gradient, 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.

'stroke'

  Value: | <paint> | inherit (See Specifying paint)
  Initial: | none
  Applies to: | shapes and text content elements
  Inherited: | yes
  Percentages: | N/A
  Media: | visual
  Animatable: | yes
  Computed value: | "none", system paint, specified <color> value or absolute IRI

The 'stroke' property shall paint along the outline of the given graphics element.

A subpath (see Paths) consisting of a single moveto shall not be stroked. A subpath consisting of a moveto and lineto to the same exact location or a subpath consisting of a moveto and a closepath shall not be stroked if the 'stroke-linecap' property has a value of butt and 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.

This property contributes to an element's decorated bounding box.

'stroke-width'

  Value: | <length> | inherit
  Initial: | 1
  Applies to: | shapes and text content elements
  Inherited: | yes
  Percentages: | N/A
  Media: | visual
  Animatable: | yes
  Computed value: | Specified value, except inherit

<length>
  The width of the stroke which shall be used on the current object.
  No stroke shall be painted for a zero value. A negative value is unsupported and must be treated as if the stroke had not been specified.

This property contributes to an element's decorated bounding box.

'stroke-linecap'

  Value: | butt | round | square | inherit
  Initial: | butt
  Applies to: | shapes and text content elements
  Inherited: | yes
  Percentages: | N/A
  Media: | visual
  Animatable: | yes
  Computed value: | Specified value, except inherit

'stroke-linecap' specifies the shape which shall be used at the end of open subpaths when they are stroked.

butt
  The shape drawn at the end of open subpaths shall be as per the drawing below.
round
  The shape drawn at the end of open subpaths shall be as per the drawing below.
square
  The shape drawn at the end of open subpaths shall be as per the drawing below.

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

This property contributes to an element's decorated bounding box.

'stroke-linejoin'

  Value: | miter | round | bevel | inherit
  Initial: | miter
  Applies to: | shapes and text content elements
  Inherited: | yes
  Percentages: | N/A
  Media: | visual
  Animatable: | yes
  Computed value: | Specified value, except inherit

'stroke-linejoin' specifies the shape which shall be used at the corners of shapes when they are stroked.

miter
  The shape drawn at the corner of shapes shall be as per the drawing below.
round
  The shape drawn at the corner of shapes shall be as per the drawing below.
bevel
  The shape drawn at the corner of shapes shall be as per the drawing below.

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

This property contributes to an element's decorated bounding box.

'stroke-miterlimit'

  Value: | <miterlimit> | inherit
  Initial: | 4
  Applies to: | shapes and text content elements
  Inherited: | yes
  Percentages: | N/A
  Media: | visual
  Animatable: | yes
  Computed value: | Specified value, except inherit

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

<miterlimit>
  The limit on the ratio of the miter length to the 'stroke-width'. The value of <miterlimit> must be a number greater than or equal to 1. Any other value shall be treated as unsupported and processed as if the property had not been specified.

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

    miterLimit = miterLength / stroke-width = 1 / sin(theta / 2)

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

This property contributes to an element's decorated bounding box.

'stroke-dasharray'

  Value: | none | <list-of-lengths> | inherit
  Initial: | none
  Applies to: | shapes and text content elements
  Inherited: | yes
  Percentages: | N/A
  Media: | visual
  Animatable: | yes (non-additive)
  Computed value: | Specified value, except inherit

'stroke-dasharray' specifies the pattern of dashes and gaps that shall be used to stroke paths. The <list-of-lengths> contains the list of <length>s that specify the lengths of alternating dashes and gaps that must be used. If an odd number of values is provided, then the list of values shall be repeated to yield an even number of values. Thus, stroke-dasharray="5,3,2" is equivalent to stroke-dasharray="5,3,2,5,3,2". The computed value of the attribute 'stroke-linecap' is applied to both sides of each dash. If a dash has zero length, linecaps are still added if the stroke-linecap values round and square are used.

none
  Indicates that no dashing shall be used. If stroked, the line must be drawn solid.
<list-of-lengths>
  The list of <length>s that specify the lengths of alternating dashes and gaps that must be used. A negative <length> value shall be treated as unsupported and processed as if the property had not been specified. If the sum of the <length>s is zero, then the stroke shall be rendered as if a value of none were specified.

Note: Certain cases regarding the behavior of 'stroke-dasharray' are not fully specified because SVG Tiny implementations often rely on underlying graphics libraries with predetermined behaviors they cannot easily change. Examples include: rendering of 'stroke-linejoin' and 'stroke-linecap' in case a dash ends exactly at a corner of two path segments, continuation of stroke-dasharray in subpaths, and others. These cases may be fully specified in version SVG 1.2 Full. Additional attributes, such as dash-caps that can be defined separately from linecaps may be added. Authors are encouraged not to rely on a specific behavior of a specific viewer for 'stroke-dasharray' regarding these currently unspecified cases.

'stroke-dashoffset'

  Value: | <length> | inherit
  Initial: | 0
  Applies to: | shapes and text content elements
  Inherited: | yes
  Percentages: | N/A
  Media: | visual
  Animatable: | yes
  Computed value: | Specified value, except inherit

'stroke-dashoffset' specifies the distance into the dash pattern that must be used to start the dash. When rendering a 'path' element with multiple subpaths, the value of 'stroke-dashoffset' should start from scratch with the original value of 'stroke-dashoffset' for each subpath. SVG 1.2 Full may be stricter and also add an additional attribute to change this behavior.

<length>
  Values can be negative.

'stroke-opacity'

  Value: | <opacity-value> | inherit
  Initial: | 1
  Applies to: | shapes and text content elements
  Inherited: | yes
  Percentages: | N/A
  Media: | visual
  Animatable: | yes
  Computed value: | Specified value, except inherit

'stroke-opacity' specifies the opacity of the painting operation used to stroke the current object. (See Painting shapes and text.)

<opacity-value>
  The opacity of the painting operation that is to be used to stroke the current object. Any values outside the range 0.0 (fully transparent) to 1.0 (fully opaque) must be clamped to this range. (See Clamping values which are restricted to a particular range.)

Related property: 'fill-opacity'.

## 11.5 Non-scaling stroke

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

'vector-effect'

  Value: | non-scaling-stroke | none | inherit
  Initial: | none
  Applies to: | graphics elements
  Inherited: | no
  Percentages: | N/A
  Media: | visual
  Animatable: | yes
  Computed value: | Specified value, except inherit

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

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

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

Example: non-scaling-stroke.svg

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

      <desc>Example non-scaling stroke</desc>
      <rect x="1" y="1" width="598" height="398" fill="none" stroke="black"/>

      <g transform="scale(9,1)">
        <line stroke="black" stroke-width="5" x1="10" y1="50" x2="10" y2="350"/>
        <line vector-effect="non-scaling-stroke" stroke="black" stroke-width="5"
            x1="32" y1="50" x2="32" y2="350"/>
        <line vector-effect="none" stroke="black" stroke-width="5"
            x1="55" y1="50" x2="55" y2="350"/>
      </g>

    </svg>

## 11.6 Simple alpha compositing

Graphics elements are blended into the elements already rendered on the canvas using simple alpha compositing, in which the resulting color and opacity at any given pixel on the canvas must be the result of the following formulas (all color values use premultiplied alpha):

         Er, Eg, Eb    - Element color value
         Ea            - Element alpha value
         Cr, Cg, Cb    - Canvas color value (before blending)
         Ca            - Canvas alpha value (before blending)
         Cr', Cg', Cb' - Canvas color value (after blending)
         Ca'           - Canvas alpha value (after blending)

         Ca' = 1 - (1 - Ea) * (1 - Ca)
         Cr' = (1 - Ea) * Cr + Er
         Cg' = (1 - Ea) * Cg + Eg
         Cb' = (1 - Ea) * Cb + Eb

The following rendering properties, which provide information about the color space in which to perform the compositing operations, apply to compositing operations:

- 'color-rendering'

### 11.6.1 Compositing the currentColor value

The currentColor value may be assigned a color value that has an opacity component. This opacity value is used in the rendering operation using the alpha compositing method described above. That is, the opacity value in currentColor is used when compositing the color into a paint server (which may have its own values for opacity).

## 11.7 The 'viewport-fill' property

SVG enables the author to specify a solid color which will be used to fill the viewport of any element that creates a viewport, such as the 'svg' element.

The 'viewport-fill' property specifies the color which shall be used to fill the viewport created by a particular element. It must cause the entire canvas of the element that it applies to to be filled with the specified solid color. That canvas may then be clipped by that element's 'viewBox'.

'viewport-fill'

  Value: | none | currentColor | <color> | inherit
  Initial: | none
  Applies to: | viewport-creating elements
  Inherited: | no
  Percentages: | N/A
  Media: | visual
  Animatable: | yes
  Computed value: | "none" or specified <color> value, except inherit

If the value of 'viewport-fill' is none, then no paint operation is applied to the viewport.

Below is an example of 'viewport-fill'.

Example: 11_02.svg

    <?xml version="1.0"?>
    <svg xmlns="http://www.w3.org/2000/svg" version="1.2" baseProfile="tiny"
         viewport-fill="red">

      <desc>
        Everything here has a red background.
        The rectangle is not filled, so the red background will show through.
      </desc>

      <rect x="20" y="20" width="100" height="100" fill="none" stroke="black"/>

    </svg>

Here is a slightly more complex example. The 'viewBox' gives a coordinate system 300 units wide and 100 units high. The rendering shows what happens when this is displayed inside a square viewport.

Example: 11_03.svg

    <?xml version="1.0"?>
    <svg xmlns="http://www.w3.org/2000/svg" version="1.2" baseProfile="tiny"
         viewBox="0 0 300 100" viewport-fill="yellow">

      <desc>
        The viewport has a yellow background.
        The rectangle is filled and covers the viewport, so the yellow
        background will only show through in the "leftovers" if the
        aspect ratio of the viewport differs from that of the viewBox.
      </desc>

      <rect x="0" y="0" width="300" height="100" fill="red" fill-opacity="0.3" stroke="black"/>

    </svg>

The filling of the viewport is the first operation in the rendering chain of an element. Therefore:

- The viewport fill operation happens before filling and stroking.
- The viewport fill operation occurs before compositing, and thus is part of the input to the compositing operations.
- The viewport fill operation renders into the element's conceptual offscreen buffer, and thus opacity applies as usual.
- Viewport fill is not affected by the 'fill' or 'fill-opacity' properties.

## 11.8 The 'viewport-fill-opacity' property

The 'viewport-fill-opacity' property specifies the opacity of the 'viewport-fill' that shall be used for a particular element.

'viewport-fill-opacity'

  Value: | <opacity-value> | inherit
  Initial: | 1.0
  Applies to: | viewport-creating elements
  Inherited: | no
  Percentages: | N/A
  Media: | visual
  Animatable: | yes
  Computed value: | Specified value, except inherit

<opacity-value>
  The opacity of the painting operation that is to be used to fill the viewport. Any values outside the range 0.0 (fully transparent) to 1.0 (fully opaque) must be clamped to this range. (See Clamping values which are restricted to a particular range.)

## 11.9 Controlling visibility and rendering

SVG uses two properties, 'display' and 'visibility', to control the rendering of graphics elements or (in the case of the 'display' property) container elements. Neither of these two properties affects the objects existence in the DOM, i.e. no matter what value of these properties the object still remains in the DOM.

The differences between the two properties are as follows:

- When applied to a container element, setting 'display' to none causes the container and all of its children to be excluded from the rendering tree; thus, it acts on groups of elements as a group. 'visibility', however, only applies to individual graphics elements. Setting 'visibility' to hidden on a 'g' will make its children visually invisible as long as the children do not specify their own 'visibility' properties as visible.
- When the 'display' property is set to none, then the given element does not become part of the rendering tree. With 'visibility' set to hidden, however, processing occurs as if the element were part of the rendering tree and still taking up space, but not actually visually rendered onto the canvas. This distinction has implications for the 'tspan' element, event processing, and for bounding box calculations. If 'display' is set to none on a 'tspan' then the text string is ignored for the purposes of text layout; however, if 'visibility' is set to hidden, the text string is used for text layout (i.e., it takes up space) even though it is not visually rendered on the canvas. Regarding events, if 'display' is set to none, the element receives no events which require the element to be in the rendering tree (for example mouse events); however, if 'visibility' is set to hidden, the element might still receive events, depending on the value of property 'pointer-events'. The geometry of a graphics element with 'display' set to none is not included in bounding box calculations; however, even if 'visibility' is to hidden, the geometry of the graphics element still contributes to bounding box calculations.

'display'

  Value: | inline | block | list-item | run-in | compact | marker | table | inline-table | table-row-group | table-header-group | table-footer-group | table-row | table-column-group | table-column | table-cell | table-caption | none | inherit
  Initial: | inline
  Applies to: | 'svg', 'g', 'switch', 'a', 'foreignObject', graphics elements (including the text content block elements), media elements and text sub-elements (e.g., 'tspan' and 'a')
  Inherited: | no
  Percentages: | N/A
  Media: | all
  Animatable: | yes
  Computed value: | Specified value, except inherit

A value of display="none" indicates that the given element and its children shall not be rendered directly or made audible (i.e., those elements are not present in the rendering tree). Any computed value other than none indicates that the given element shall be rendered or made audible by the SVG user agent.

The 'display' property only affects the direct rendering or audibility of a given element, whereas it does not prevent elements from being referenced by other elements.

Elements with display="none" do not take up space in text layout operations, do not receive events and do not contribute to bounding box calculations.

Except for any additional information provided in this specification, the normative definition of this property is found in CSS 2 ([CSS2], section 9.2.5).

'visibility'

  Value: | visible | hidden | collapse | inherit
  Initial: | visible
  Applies to: | graphics elements (including the text content block elements), media elements and text sub-elements (e.g., 'tspan' and 'a')
  Inherited: | yes
  Percentages: | N/A
  Media: | all
  Animatable: | yes
  Computed value: | Specified value, except inherit

visible
  The current graphics element or media element shall be visible.
hidden or collapse
  The current graphics element or media element shall be invisible (i.e., nothing is painted on the canvas).

Note that, unlike the 'display' property, the 'visibility' property does not have any affect on the audibility of any media element. To control the audibility of an element, use the 'display' or 'audio-level' properties.

Note that if the 'visibility' property is set to hidden on a 'tspan' element, then the text is invisible but shall still takes up space in text layout calculations.

Depending on the value of property 'pointer-events', graphics elements which have their 'visibility' property set to hidden still might receive events.

Except for any additional information provided in this specification, the normative definition of this property is found in CSS 2 ([CSS2], section 11.2).

## 11.10 Rendering hints

### 11.10.1 The 'color-rendering' property

The creator of SVG content might want to provide a hint to the implementation about how to make speed versus 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.

'color-rendering'

  Value: | auto | optimizeSpeed | optimizeQuality | inherit
  Initial: | auto
  Applies to: | container elements, graphics elements and 'animateColor'
  Inherited: | yes
  Percentages: | N/A
  Media: | visual
  Animatable: | yes
  Computed value: | Specified value, except inherit

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

### 11.10.2 The 'shape-rendering' property

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.

'shape-rendering'

  Value: | auto | optimizeSpeed | crispEdges | geometricPrecision | inherit
  Initial: | auto
  Applies to: | shapes
  Inherited: | yes
  Percentages: | N/A
  Media: | visual
  Animatable: | yes
  Computed value: | Specified value, except inherit

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

### 11.10.3 The 'text-rendering' property

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.

'text-rendering'

  Value: | auto | optimizeSpeed | optimizeLegibility | geometricPrecision | inherit
  Initial: | auto
  Applies to: | text content block elements
  Inherited: | yes
  Percentages: | N/A
  Media: | visual
  Animatable: | yes
  Computed value: | Specified value, except inherit

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

### 11.10.4 The 'image-rendering' property

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.

'image-rendering'

  Value: | auto | optimizeSpeed | optimizeQuality | inherit
  Initial: | auto
  Applies to: | images
  Inherited: | yes
  Percentages: | N/A
  Media: | visual
  Animatable: | yes
  Computed value: | Specified value, except inherit

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

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

### 11.10.5 The 'buffered-rendering' property

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:

'buffered-rendering'

  Value: | auto | dynamic | static | inherit
  Initial: | auto
  Applies to: | container elements and graphics elements
  Inherited: | no
  Percentages: | N/A
  Media: | visual
  Animatable: | yes
  Computed value: | Specified value, except inherit

auto
  Indicates that the user agent is expected to use a reasonable compromise between speed of update and resource allocation.
dynamic
  Indicates that the element is expected to be modified often.
static
  Indicates that the element is not expected to be modified often. This suggests that user agent may be able to allocate resources, such as an offscreen buffer, that would allow increased performance in redraw. It does not mean that the element will never change. If an element is modified when the value is 'static', then redraw might have reduced performance.

## 11.11 Inheritance of painting properties

The values of any of the painting properties described 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.

Example Inheritance

Example: 11_01.svg

    <?xml version="1.0"?>
    <svg xmlns="http://www.w3.org/2000/svg" version="1.2" baseProfile="tiny"
         width="7cm" height="2cm" viewBox="0 0 700 200">

      <desc>Gradients apply to leaf nodes</desc>

      <g>
        <defs>
          <linearGradient xml:id="MyGradient" gradientUnits="objectBoundingBox">
            <stop offset="0" stop-color="#F60"/>
            <stop offset="1" stop-color="#FF6"/>
          </linearGradient>
        </defs>

        <rect x="1" y="1" width="698" height="198"
              fill="none" stroke="blue" stroke-width="2"/>

        <g fill="url(#MyGradient)">
          <rect x="100" y="50" width="200" height="100"/>
          <rect x="400" y="50" width="200" height="100"/>
       </g>
      </g>
    </svg>

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.)

## 11.12 Object and group opacity: the 'opacity' property

There are several opacity properties within SVG:

- Solid color opacity
- Fill opacity
- Stroke opacity
- Gradient stop opacity
- Viewport fill opacity
- Object/group opacity (described here)

Except for object/group opacity (described just below), all other opacity properties are involved in intermediate rendering operations. Object/group opacity can be thought of conceptually as a postprocessing operation. Conceptually, after the object/group is rendered into an RGBA offscreen image, the object/group opacity setting specifies how to blend the offscreen image into the current background.

Object/group opacity can, if applied to container elements, be a resource intensive operation. Therefore this version of SVG restricts this property to only be set on, and only apply to, the 'image' element. Note: if the value is set to inherit, then the initial value of 1 for the opacity property will be used, meaning full opacity. This is the same as not specifying it at all.

'opacity'

  Value: | <opacity-value> | inherit
  Initial: | 1
  Applies to: | 'image' element
  Inherited: | no
  Percentages: | N/A
  Media: | visual
  Animatable: | yes
  Computed value: | Specified value, except inherit

<opacity-value>
  The uniform opacity setting that must applied across an entire object. Any values outside the range 0.0 (fully transparent) to 1.0 (fully opaque) must be clamped to this range. (See Clamping values which are restricted to a particular range.)

Below is an example of 'opacity' which illustrates the difference in behavior between SVG Basic/Full 1.1 and SVG Tiny 1.2.

Example: struct-image-201-t.svg

    <?xml version="1.0" encoding="UTF-8"?>
    <svg version="1.2" baseProfile="tiny" xml:id="svg-root" width="100%" height="100%"
      viewBox="0 0 480 360" xmlns="http://www.w3.org/2000/svg" xmlns:ev="http://www.w3.org/2001/xml-events"
      xmlns:xlink="http://www.w3.org/1999/xlink">
      <!--======================================================================-->
      <!--=  Copyright 2007 World Wide Web Consortium, (Massachusetts          =-->
      <!--=  Institute of Technology, European Research Consortium for         =-->
      <!--=  Informatics and Mathematics (ERCIM), Keio University).            =-->
      <!--=  All Rights Reserved.                                              =-->
      <!--=  See http://www.w3.org/Consortium/Legal/.                          =-->
      <!--======================================================================-->
      <metadata>
          <p>
            This test shows the differences in opacity-handling between SVG Tiny 1.2 and SVG Full 1.1.
          </p>
    	  <p>
    		The test has passed if the leftmost column looks like either of the other two columns.
    		SVG Tiny 1.2 requires only what is portrayed by the middle column, but does not require
    		user agents that implement both SVG 1.1 and 1.2 Tiny to follow the more limited
    		opacity-handling in 1.2 Tiny.
    	  </p>
    	  <p>
    		In SVG Tiny 1.2 the opacity property is only allowed on the image element itself.
    		If it's encountered anywhere else it must be treated as an unsupported value.

    		NOTE: This test is not valid 1.2 Tiny because it's using opacity on something
    		other than the image element.
    	  </p>
    </metadata>
      <title xml:id="test-title">&#36;RCSfile: struct-image-201-t.svg,v $</title>
      <defs>
        <font-face
          font-family="SVGFreeSansASCII"
          unicode-range="U+0-7F">
          <font-face-src>
            <font-face-uri xlink:href="SVGFreeSans.svg#ascii"/>
          </font-face-src>
        </font-face>
      </defs>
      <g xml:id="test-body-content" font-family="SVGFreeSansASCII,sans-serif" font-size="18">

    	<text x="240" y="70" text-anchor="middle" font-size="32">Test opacity</text>

    	<g id="test" transform="translate(-100 0)">
    		<text x="240" y="120" text-anchor="middle">Test</text>
    		<text x="240" y="130" text-anchor="middle" font-size="9">Mouseover to compare</text>
    		<rect id="r1" x="200" y="135" height="20" width="80" fill="green"/>
    		<rect id="r2" x="200" y="160" height="20" width="80" fill="green"/>
    		<rect id="r3" x="200" y="185" height="20" width="80" fill="green"/>
    		<rect id="r4" x="200" y="210" height="20" width="80" fill="green"/>

    		<g pointer-events="none">
    			<image width="460" height="20" x="10" y="135" xlink:href="1pixelwhite.png" preserveAspectRatio="none" opacity="0.25"/>
    			<g opacity="0.5">
    				<image width="460" height="20" x="10" y="160" xlink:href="1pixelwhite.png" preserveAspectRatio="none" opacity="0.5"/>
    				<rect id="r5" x="200" y="185" height="20" width="80" fill="white" opacity="0.5"/>

    			</g>
    			<g opacity="0.75">
    				<g opacity="inherit">
    					<image width="460" height="20" x="10" y="210" xlink:href="1pixelwhite.png" preserveAspectRatio="none" opacity="inherit"/>
    				</g>
    			</g>
    		</g>

    		<ev:listener event="mouseover" observer="r1" handler="#handler"/>
    		<ev:listener event="mouseout" observer="r1" handler="#handler"/>
    		<ev:listener event="mouseover" observer="r2" handler="#handler"/>
    		<ev:listener event="mouseout" observer="r2" handler="#handler"/>
    		<ev:listener event="mouseover" observer="r3" handler="#handler"/>
    		<ev:listener event="mouseout" observer="r3" handler="#handler"/>
    		<ev:listener event="mouseover" observer="r4" handler="#handler"/>
    		<ev:listener event="mouseout" observer="r4" handler="#handler"/>
    		<handler id="handler">
    			if(event.type == "mouseover")
    			{
    				event.target.setFloatTrait("width", 280);
    				if(event.target.id == "r3")
    					document.getElementById("r5").setFloatTrait("width", 280);
    			}
    			else
    			{
    				event.target.setFloatTrait("width", 80);
    				if(event.target.id == "r3")
    					document.getElementById("r5").setFloatTrait("width", 80);
    			}
    		</handler>
    	</g>

    	<g id="tiny12reference">
    		<text x="240" y="120" text-anchor="middle">Tiny 1.2 ref</text>
    		<rect x="200" y="135" height="20" width="80" fill="green"/>
    		<rect x="200" y="160" height="20" width="80" fill="green"/>
    		<rect x="200" y="185" height="20" width="80" fill="green"/>
    		<rect x="200" y="210" height="20" width="80" fill="green"/>
    		<rect x="200" y="135" height="20" width="80" fill="white" fill-opacity="0.25"/>
    		<rect x="200" y="160" height="20" width="80" fill="white" fill-opacity="0.5"/>
    		<rect x="200" y="185" height="20" width="80" fill="white" fill-opacity="1"/>
    		<rect x="200" y="210" height="20" width="80" fill="white" fill-opacity="1"/>
    	</g>

    	<g id="full11reference" transform="translate(100 0)">
    		<text x="240" y="120" text-anchor="middle">Full 1.1 ref</text>
    		<rect x="200" y="135" height="20" width="80" fill="green"/>
    		<rect x="200" y="160" height="20" width="80" fill="green"/>
    		<rect x="200" y="185" height="20" width="80" fill="green"/>
    		<rect x="200" y="210" height="20" width="80" fill="green"/>
    		<rect x="200" y="135" height="20" width="80" fill="white" fill-opacity="0.25"/>
    		<rect x="200" y="160" height="20" width="80" fill="white" fill-opacity="0.25"/>
    		<rect x="200" y="185" height="20" width="80" fill="white" fill-opacity="0.25"/>
    		<rect x="200" y="210" height="20" width="80" fill="white" fill-opacity="0.421875"/>
    	</g>

      </g>
      <g font-family="SVGFreeSansASCII,sans-serif" font-size="32">
      <text xml:id="revision" x="10" y="340" stroke="none"
        fill="black">&#36;Revision: 1.4 $</text>
      </g>
      <rect xml:id="test-frame" x="1" y="1" width="478" height="358" fill="none" stroke="#000"/>
    </svg>

## 11.13 Color

In SVG Tiny 1.2, all colors are specified in the sRGB color space [SRGB]. SVG Tiny 1.2 user agents are not required to, but may, support color management. However, SVG Tiny 1.2 user agents should apply gamma correction if the response curve of the display system differs from that of sRGB.

### 11.13.1 Syntax for color values

Five syntactical forms are specified for SVG Tiny 1.2, and all of them must be supported in a conforming SVG Interpreter:

Three digit hex — #rgb
  Each hexadecimal digit, in the range 0 to F, represents one sRGB color component in the order red, green and blue. The digits A to F may be in either uppercase or lowercase. The value of the color component is obtained by replicating digits, so 0 become 00, 1 becomes 11, F becomes FF. This compact syntactical form can represent only 4096 colors. Examples: #000 (i.e. black) #fff (i.e. white) #6CF (i.e. #66CCFF, rgb(102, 204, 255)).
Six digit hex — #rrggbb
  Each pair of hexadecimal digits, in the range 0 to F, represents one sRGB color component in the order red, green and blue. The digits A to F may be in either uppercase or lowercase.This syntactical form, originally introduced by HTML, can represent 16777216 colors. Examples: #9400D3 (i.e. a dark violet), #FFD700 (i.e. a golden color).
Integer functional — rgb(rrr, ggg, bbb)
  Each integer represents one sRGB color component in the order red, green and blue, separated by a comma and optionally by white space. Each integer is in the range 0 to 255. This syntactical form can represent 16777216 colors. Examples: rgb(233, 150, 122) (i.e. a salmon pink), rgb(255, 165, 0) (i.e. an orange).
Float functional — rgb(R%, G%, B%)
  Each percentage value represents one sRGB color component in the order red, green and blue, separated by a comma and optionally by white space. For colors inside the sRGB gamut, the range of each component is 0.0% to 100.0% and an arbitrary number of decimal places may be supplied. Scientific notation is not supported. This syntactical form can represent an arbitrary range of colors, completely covering the sRGB gamut. Color values where one or more components are below 0.0% or above 100.0% represent colors outside the sRGB gamut Examples: rgb(12.375%, 34.286%, 28.97%).
Color keyword
  The sixteen color keywords below (originally from HTML 4 [HTML4]) must be supported, with the further restriction that they must be lowercase.

### 11.13.2 HTML color keywords

| black | rgb(0, 0, 0) |  | green | rgb(0, 128, 0)
| silver | rgb(192, 192, 192) |  | lime | rgb(0, 255, 0)
| gray | rgb(128, 128, 128) |  | olive | rgb(128, 128, 0)
| white | rgb(255, 255, 255) |  | yellow | rgb(255, 255, 0)
| maroon | rgb(128, 0, 0) |  | navy | rgb(0, 0, 128)
| red | rgb(255, 0, 0) |  | blue | rgb(0, 0, 255)
| purple | rgb(128, 0, 128) |  | teal | rgb(0, 128, 128)
| fuchsia | rgb(255, 0, 255) |  | aqua | rgb(0, 255, 255)

## 11.14 Paint servers

With SVG, you can fill (i.e., paint the interior of) or stroke (i.e., paint the outline of) shapes and text using one of the following:

- color (using <color> or a reference to a 'solidColor' element)
- a system paint
- gradients (linear or radial)

SVG uses the general notion of a paint server. Gradients and patterns are just specific types of built-in paint servers. The 'solidColor' element is another built-in paint server, described in Color.

Apart from system paint, paint servers are referenced using a local IRI reference on a 'fill' or 'stroke' property.

### 11.14.1 System paint servers

The following list of system paint servers must be supported. If a paint specification specifies one of the system paint servers, then the user agent must either paint using a system-provided paint server or paint with a substitute paint server, such as a color or gradient. System paint servers often depend on the operating system, user choices, and the implementation. Substitute paint servers should attempt to match the appearance of corresponding user interface elements on the platform, including user color choices. In environments which do not provide adequate system paint server APIs, a conformant user agent may use substitute paint servers which do not necessarily match the environment's system paint servers.

The computed value of a paint specified as a system paint is the specified value.

ActiveBorder
  Active window border.
ActiveCaption
  Active window caption.
AppWorkspace
  Background color of multiple document interface.
Background
  Desktop background.
ButtonFace
  Face color for three-dimensional display elements.
ButtonHighlight
  Dark shadow for three-dimensional display elements (for edges facing away from the light source).
ButtonShadow
  Shadow color for three-dimensional display elements.
ButtonText
  Text on push buttons.
CaptionText
  Text in caption, size box, and scrollbar arrow box.
GrayText
  Disabled ('grayed') text.
Highlight
  Item(s) selected in a control.
HighlightText
  Text of item(s) selected in a control.
InactiveBorder
  Inactive window border.
InactiveCaption
  Inactive window caption.
InactiveCaptionText
  Color of text in an inactive caption.
InfoBackground
  Background color for tooltip controls.
InfoText
  Text color for tooltip controls.
Menu
  Menu background.
MenuText
  Text in menus.
Scrollbar
  Scroll bar gray area.
ThreeDDarkShadow
  Dark shadow for three-dimensional display elements.
ThreeDFace
  Face color for three-dimensional display elements.
ThreeDHighlight
  Highlight color for three-dimensional display elements.
ThreeDLightShadow
  Light color for three-dimensional display elements (for edges facing the light source).
ThreeDShadow
  Dark shadow for three-dimensional display elements.
Window
  Window background.
WindowFrame
  Window frame.
WindowText
  Text in windows.

### 11.14.2 The 'solidColor' element

The 'solidColor' element is a paint server that provides a single color with opacity. It can be referenced like the other paint servers (i.e. gradients).

Schema: solidColor

        <define name='solidColor'>
          <element name='solidColor'>
            <ref name='solidColor.AT'/>
            <ref name='solidColor.CM'/>
          </element>
        </define>

        <define name='solidColor.CM'>
          <zeroOrMore>
            <choice>
              <ref name='svg.Desc.group'/>
              <ref name='svg.Animate.group'/>
              <ref name='svg.Handler.group'/>
              <ref name='svg.Discard.group'/>
            </choice>
          </zeroOrMore>
        </define>

        <define name='solidColor.AT' combine='interleave'>
          <ref name='svg.Properties.attr'/>
          <ref name='svg.Core.attr'/>
        </define>

The 'solid-color' property specifies the color that shall be used for this 'solidColor' element. The keyword currentColor can be specified in the same manner as within a <paint> specification for the 'fill' and 'stroke' properties.

'solid-color'

  Value: | currentColor | <color> | inherit
  Initial: | black
  Applies to: | 'solidColor' elements
  Inherited: | no
  Percentages: | N/A
  Media: | visual
  Animatable: | yes
  Computed value: | Specified <color> value, except inherit

The 'solid-opacity' property defines the opacity of the 'solidColor'.

'solid-opacity'

  Value: | <opacity-value> | inherit
  Initial: | 1
  Applies to: | 'solidColor' elements
  Inherited: | no
  Percentages: | N/A
  Media: | visual
  Animatable: | yes
  Computed value: | Specified value, except inherit

<opacity-value>
  The opacity of the 'solidColor'. Any values outside the range 0.0 (fully transparent) to 1.0 (fully opaque) must be clamped to this range. (See Clamping values which are restricted to a particular range.)

The 'solidColor' paint server applies paint of the specified color using the opacity defined in 'solid-opacity'. The value of 'solid-opacity' is independent of the opacity used to render the paint via 'fill' or 'stroke' (see alpha compositing).

Properties shall inherit into the 'solidColor' element from its ancestors; properties shall not inherit from the element referencing the 'solidColor' element.

'solidColor' elements are never rendered directly; their only usage is as something that can be referenced using the 'fill' and 'stroke' properties. The 'display' property does not apply to the 'solidColor' element; thus, 'solidColor' elements are not directly rendered even if the 'display' property is set to a value other than none, and 'solidColor' elements are available for referencing even when the 'display' property on the 'solidColor' element or any of its ancestors is set to none.

Below is an example of the 'solidColor' element:

Example: solidcolor.svg

    <?xml version="1.0" encoding="UTF-8"?>
    <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
         version="1.2" baseProfile="tiny"
         width="480" height="360" viewBox="0 0 480 360">

      <title>'solidColor' example</title>

      <defs>
        <solidColor xml:id="solidMaroon" solid-color="maroon" solid-opacity="0.7"/>
      </defs>

      <g>
        <circle transform="translate(100, 150)" fill="url(#solidMaroon)" r="30"/>
        <rect fill="url(#solidMaroon)" transform="translate(190, 150)" x="-30" y="-30" width="60" height="60"/>
        <path fill="url(#solidMaroon)" transform="translate(270, 150)"  d="M 0 -30 L 30 30 L -30 30 Z" />
        <text fill="url(#solidMaroon)" transform="translate(340, 150)" y="21" font-weight="bold" font-size="60">A</text>
      </g>
    </svg>

### 11.14.3 The 'color' property

The 'color' property, which is defined in CSS2 as the color of text, does not directly apply to SVG elements. The value of the SVG color property may however be used to provide an indirect value for those properties which allow the currentColor keyword: the 'fill', 'stroke', 'solid-color' and 'stop-color' properties.

'color'

  Value: | <color> | inherit
  Initial: | depends on user agent
  Applies to: | None. Indirectly affects other properties via currentColor
  Inherited: | yes
  Percentages: | N/A
  Media: | visual
  Animatable: | yes
  Computed value: | Specified <color> value, except inherit

Except for any additional information provided in this specification, the normative definition of the property is found in CSS 2 ([CSS2], section 14.1).

## 11.15 Gradients

Gradients consist of continuously smooth color transitions along a vector from one color to another, possibly followed by additional transitions along the same vector to other colors. SVG provides for two types of gradients, 'linearGradient' and 'radialGradient'.

Once defined, gradients are then referenced using 'fill' or 'stroke' properties on a given graphics element to indicate that the given element shall be filled or stroked with the referenced gradient.

### 11.15.1 Linear gradients

Linear gradients are defined by a 'linearGradient' element.

Schema: linearGradient

        <define name='linearGradient'>
          <element name='linearGradient'>
            <ref name='linearGradient.AT'/>
            <ref name='GradientCommon.CM'/>
          </element>
        </define>

        <define name='linearGradient.AT' combine='interleave'>
          <ref name='svg.Properties.attr'/>
          <ref name='svg.GradientCommon.attr'/>
          <ref name='svg.Core.attr'/>
          <ref name='svg.X12Y12.attr'/>
        </define>

Attribute definitions:

gradientUnits = "userSpaceOnUse" | "objectBoundingBox"

  Defines the coordinate system for attributes 'x1', 'y1', 'x2', 'y2' that shall be used when rendering the gradient.

  If gradientUnits="userSpaceOnUse", 'x1', 'y1', 'x2', 'y2' shall 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).

  If gradientUnits="objectBoundingBox", the user coordinate system for attributes 'x1', 'y1', 'x2', 'y2' shall be established using the bounding box of the element to which the gradient is applied (see Object bounding box units).

  When gradientUnits="objectBoundingBox" the stripes of the linear gradient shall be 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,0) is at the top/right of the object bounding box). When the object's bounding box is not square, the stripes that are conceptually perpendicular to the gradient vector within object bounding box space shall render non-perpendicular relative to the gradient vector in user space due to application of the non-uniform scaling transformation from bounding box space to user space.

  The lacuna value is 'objectBoundingBox'.

  Animatable: yes.

x1 = "<coordinate>"

  'x1', 'y1', 'x2', 'y2' define a gradient vector for the linear gradient. This gradient vector provides starting and ending points onto which the gradient stops shall be mapped. The values of 'x1', 'y1', 'x2', 'y2' must be numbers.

  The lacuna value is '0'.

  Animatable: yes.

y1 = "<coordinate>"

  See 'x1'.

  The lacuna value is '0'.

  Animatable: yes.

x2 = "<coordinate>"

  See 'x1'.

  The lacuna value is '1'.

  Animatable: yes.

y2 = " <coordinate>"
  See 'x1'.

  The lacuna value is '0'.

  Animatable: yes.

If 'x1' = 'x2' and 'y1' = 'y2', then the area to be painted shall be painted as a single color using the color and opacity of the last gradient stop.

If the gradient starts or ends inside the bounds of the target rectangle the terminal colors of the gradient shall be used to fill the remainder of the target region.

Properties shall inherit into the 'linearGradient' element from its ancestors; properties shall not inherit from the element referencing the 'linearGradient' element.

'linearGradient' elements are never rendered directly; their only usage is as something that can be referenced using the 'fill' and 'stroke' properties. The 'display' property does not apply to the 'linearGradient' element; thus, 'linearGradient' elements are not directly rendered even if the 'display' property is set to a value other than none, and 'linearGradient' elements are available for referencing even when the 'display' property on the 'linearGradient' element or any of its ancestors is set to none.

Example 13_01 shows how to fill a rectangle by referencing a linear gradient paint server.

Example: 13_01.svg

    <?xml version="1.0"?>
    <svg xmlns="http://www.w3.org/2000/svg" version="1.2" baseProfile="tiny"
         width="8cm" height="4cm" viewBox="0 0 800 400">

      <desc>Example 13_01 - fill a rectangle using a linear gradient paint server</desc>

      <g>
        <defs>
          <linearGradient xml:id="MyGradient">
            <stop offset="0.05" stop-color="#F60"/>
            <stop offset="0.95" stop-color="#FF6"/>
          </linearGradient>
        </defs>

        <!-- Outline the drawing area in blue -->
        <rect fill="none" stroke="blue"
              x="1" y="1" width="798" height="398"/>

        <!-- The rectangle is filled using a linear gradient paint server -->
        <rect fill="url(#MyGradient)" stroke="black" stroke-width="5"
              x="100" y="100" width="600" height="200"/>
      </g>
    </svg>

### 11.15.2 Radial gradients

Radial gradients are defined by a 'radialGradient' element.

Schema: radialGradient

        <define name='radialGradient'>
          <element name='radialGradient'>
            <ref name='radialGradient.AT'/>
            <ref name='GradientCommon.CM'/>
          </element>
        </define>

        <define name='radialGradient.AT' combine='interleave'>
          <ref name='svg.Properties.attr'/>
          <ref name='svg.GradientCommon.attr'/>
          <ref name='svg.Core.attr'/>
          <ref name='svg.CxCy.attr'/>
          <ref name='svg.R.attr'/>
        </define>

Attribute definitions:

gradientUnits = "userSpaceOnUse" | "objectBoundingBox"

  Defines the coordinate system for attributes 'cx', 'cy', 'r' that shall be used when rendering the gradient.

  If gradientUnits="userSpaceOnUse", 'cx', 'cy', 'r' shall 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).

  If gradientUnits="objectBoundingBox", the user coordinate system for attributes 'cx', 'cy', 'r' shall be established using the bounding box of the element to which the gradient is applied (see Object bounding box units).

  When gradientUnits="objectBoundingBox" the rings of the radial gradient shall be 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 shall render as elliptical due to application of the non-uniform scaling transformation from bounding box space to user space.

  The lacuna value is 'objectBoundingBox'.

  Animatable: yes.

cx = "<coordinate>"

  'cx', 'cy' and 'r' define the largest (i.e., outermost) circle for the radial gradient and the 0 gradient stop is mapped to ('cx', 'cy').

  The lacuna value is '0.5'.

  Animatable: yes.

cy = "<coordinate>"

  See 'cx'.

  The lacuna value is '0.5'.

  Animatable: yes.

r = "<length>"

  See 'cx'.

  A negative value shall be treated as unsupported. A value of zero shall cause the area to be painted as a single color using the color and opacity of the last gradient stop. The lacuna value is '0.5'.

  Animatable: yes.

If the gradient starts or ends inside the bounds of the object(s) being painted by the gradient the terminal colors of the gradient shall be used to fill the remainder of the target region.

Properties shall inherit into the 'radialGradient' element from its ancestors; properties shall not inherit from the element referencing the 'radialGradient' element.

'radialGradient' elements must never be rendered directly; their only usage is as something that can be referenced using the 'fill' and 'stroke' properties. The 'display' property does not apply to the 'radialGradient' element; thus, 'radialGradient' elements are not directly rendered even if the 'display' property is set to a value other than none, and 'radialGradient' elements are available for referencing even when the 'display' property on the 'radialGradient' element or any of its ancestors is set to none.

Example 13_02 shows how to fill a rectangle by referencing a radial gradient paint server.

Example: 13_02.svg

    <?xml version="1.0"?>
    <svg xmlns="http://www.w3.org/2000/svg" version="1.2" baseProfile="tiny"
         width="8cm" height="4cm" viewBox="0 0 800 400">

      <desc>Example 13_02 - fill a rectangle by referencing a radial gradient paint server</desc>

      <g>
        <defs>
          <radialGradient xml:id="MyGradient" gradientUnits="userSpaceOnUse"
                          cx="400" cy="200" r="300">
            <stop offset="0" stop-color="red"/>
            <stop offset="0.5" stop-color="blue"/>
            <stop offset="1" stop-color="red"/>
          </radialGradient>
        </defs>

        <!-- Outline the drawing area in blue -->
        <rect fill="none" stroke="blue"
              x="1" y="1" width="798" height="398"/>

        <!-- The rectangle is filled using a radial gradient paint server -->
        <rect fill="url(#MyGradient)" stroke="black" stroke-width="5"
              x="100" y="100" width="600" height="200"/>
      </g>
    </svg>

### 11.15.3 Defining gradient stops: the 'stop' element

The ramp of colors to use on a gradient is defined by the 'stop' elements that are child elements to either the 'linearGradient' element or the 'radialGradient' element.

Schema: stop

        <define name='stop'>
          <element name='stop'>
            <ref name='stop.AT'/>
            <ref name='stop.CM'/>
          </element>
        </define>

        <define name='stop.CM'>
          <zeroOrMore>
            <choice>
              <ref name='svg.Desc.group'/>
              <ref name='svg.Animate.group'/>
            </choice>
          </zeroOrMore>
        </define>

        <define name='stop.AT' combine='interleave'>
          <ref name='svg.Properties.attr'/>
          <ref name='svg.Core.attr'/>
          <optional>
            <attribute name='offset' svg:animatable='true' svg:inheritable='false'>
              <ref name='Number.datatype'/>
            </attribute>
          </optional>
        </define>

Attribute definitions:

offset = "<number>"

  The 'offset' attribute is a <number> which indicates where the gradient stop shall be placed. For linear gradients, the 'offset' attribute represents a location along the gradient vector. For radial gradients, it represents a relative distance from ('cx', 'cy') to the edge of the outermost/largest circle.

  The lacuna value is '0'.

  Animatable: yes.

The 'stop-color' property specifies the color that shall be used at the gradient stop. The keyword currentColor can be specified in the same manner as within a <paint> specification for the 'fill' and 'stroke' properties.

'stop-color'

  Value: | currentColor | <color> | inherit
  Initial: | black
  Applies to: | 'stop' elements
  Inherited: | no
  Percentages: | N/A
  Media: | visual
  Animatable: | yes
  Computed value: | Specified <color> value, except inherit

The 'stop-opacity' property specifies the opacity that shall be used for the gradient 'stop'.

'stop-opacity'

  Value: | <opacity-value> | inherit
  Initial: | 1
  Applies to: | 'stop' elements
  Inherited: | no
  Percentages: | N/A
  Media: | visual
  Animatable: | yes
  Computed value: | Specified value, except inherit

The gradient paint server applies paint of the specified gradient using the opacities defined by 'stop-opacity' values. The values of 'stop-opacity' are independent of the opacity used to render the paint via 'fill' or 'stroke' (see alpha compositing).

<opacity-value>
  The opacity of the 'stop-color' for the current gradient 'stop'. Any values outside the range 0.0 (fully transparent) to 1.0 (fully opaque) must be clamped to this range. (See Clamping values which are restricted to a particular range.)

Some notes on gradients:

- Any gradient offset values outside the range 0.0 to 1.0 must be clamped to this range. (See Clamping values which are restricted to a particular range.)

- It is necessary that at least two 'stop' elements are specified to have a gradient effect. If no 'stop' elements are specified, then painting shall occur as if none were specified as the paint style. If one 'stop' is specified, then painting shall occur with the solid color fill using the color defined for that gradient stop.

- Each gradient offset value is required to be equal to or greater than the previous gradient stop's offset value. If a given gradient stop's offset value is not equal to or greater than all previous offset values, then the offset value must be adjusted to be equal to the largest of all previous offset values.

- If two gradient stops have the same offset value, then the latter gradient stop shall control 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.

- Colors and opacities are interpolated separately, and the resulting gradient is composited using simple alpha compositing. In particular:

      <stop offset="0" stop-color="#F00" stop-opacity="0"/>
      <stop offset="1" stop-color="#0F0" stop-opacity="1"/>

  will produce a gradient from fully transparent red, via partly transparent dark yellow, to fully opaque lime.

- All gradient stops must be converted into the interpolation color space. Interpolation between gradient stop colors must occur in the interpolation color space.

- SVG Tiny 1.2 user agents have the option to interpolate gradients in either sRGB or in linearRGB color space. Both color spaces have the same color gamut (see [SRGB]).

- Other W3C specifications may allow alternative interpolation color spaces to be specified.