8 Painting (Filling and Stroking)


Contents


 

8.1 Introduction

<path> elements, <text> elements and basic 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.

Certain elements (i.e., <path>, <polyline>, <polygon> and <line> elements) can also have marker symbols drawn at their vertices.

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

SVG uses the general notion of a paint server. Gradients and patterns are just specific types of paint servers. For example, first you define a gradient by including a <gradient> element within a <defs>, assign an ID to that <gradient> object, and then reference that ID in a 'fill' or 'stroke' property:

<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG July 1999//EN" 
  "http://www.w3.org/Graphics/SVG/svg-19990730.dtd">
<svg width="4in" height="3in">
  <desc>Linear gradient example
  </desc>
  <g>
    <defs>
      <linearGradient id="MyGradient">
        <stop offset="0%" style="color:#F60"/>
        <stop offset="70%" style="color:#FF6"/>
      </linearGradient>
    </defs>
    <rect style="fill: url(#MyGradient)" width="20" height="15.8"/>
  </g>
</svg>

Download this example

8.2 Fill Properties

'fill'
Value:   none |
currentColor |
<color> [icc-color(<colorvalue>*)] |
inherit |
<uri> [ none | currentColor | <color> [icc-color(<colorvalue>*)] | inherit ]
Initial:   currentColor
Applies to:  all elements
Inherited:  see Inheritance of Painting Properties below
Percentages:  N/A
Media:  visual
none
Indicates that the object should not be filled.
currentColor
Indicates that the object should filled with the color specified by 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> [icc-color(<colorvalue>*)]
<color> is the explicit color (in the sRGB color space) to be used to fill the current object. SVG supports all of CSS2's <color> specifications. If an optional [icc-color(<colorvalue>*)] is provided, then the list of <colorvalue>'s is a set ICC-profile-specific color values. On platforms which support ICC-based color management, the icc-color gets precedence over the <color> (which is in the sRGB color space). For more on ICC-based colors, refer to Color.
<uri> [ none | currentColor | <color> | inherit ]
The <uri> is how you identify a fancy paint style such as a gradient, a pattern or a custom paint from extensibility. The <uri> should provide the ID of the paint server (e.g., a gradient [??? see link] or a pattern [??? see link] ) to be used to paint the current object. If the XPointer is not valid (e.g., it points to an object that doesn't exist or the object is not a valid paint server), then the paint method following the <uri> (i.e., none | currentColor | <color> | inherit) is used if provided; otherwise, no gradient will occur.

Note that graphical objects that are not closed (e.g., a <path> without a closepath at the end or a <polyline>) still can be filled. The fill operation automatically closes all open subpaths by connecting the last point of the subpath with the first point of the subpath before painting the fill.

'fill-rule'
Value:   evenodd | nonzero | inherit
Initial:   evenodd
Applies to:  all elements
Inherited:  yes
Percentages:  N/A
Media:  visual
evenodd
(??? Need detailed description plus drawings)
nonzero
(??? Need detailed description plus drawings)
'fill-opacity'
Value:   <opacity-value>
Initial:   100%
Applies to:  all elements
Inherited:  yes
Percentages:  Allowed
Media:  visual

'fill-opacity' specifies the opacity of the painting operation used to fill the current object. It is important to note that any given object can have three different opacity properties: 'fill-opacity', 'stroke-opacity' and 'opacity'. The 'fill' painting operation is done and blended into the current background (or temporary offscreen buffer, if 'opacity' is not 1.0) using the value of 'fill-opacity'. Next, The 'stroke' painting operation is done and blended into the current background (or temporary offscreen buffer, if 'opacity' is not 1.0) using the value of 'stroke-opacity'. Finally, if 'opacity' is not 1.0, the offscreen holding the object as a whole is blended into the current background.

(The above paragraph needs to be moved someplace else, such as SVG Rendering Model.)

<opacity-value>
The opacity of the painting operation used to fill the current object. If a <number> is provided, then it must be in the range of 0.0 (fully transparent) to 1.0 (fully opaque). If a percentage is provided, then it must be in the range of 0% to 100%. Any values outside of the acceptable range are rounded to the nearest acceptable value.
'fill-params'
Value:   <string> | inherit
Initial:   Empty string
Applies to:  all elements
Inherited:  yes
Percentages:  Paint server-specific.
Media:  visual

'fill-params' specifies an arbitrary <string> which is passed to the current fill paint server. The meaning of <string> is paint server-specific. None of the built-in paint servers use 'fill-params'. It is meant as a way to pass parameters to a custom paint servers defined via paint server extensibility.

<string>
A <string> containing parameters which should be passed to the current fill paint server.

8.3 Stroke Properties

'stroke'
Value:   none |
currentColor |
<color> [icc-color(<number>*)] |
inherit |
<uri> [ none | currentColor | <color> | inherit ]
Initial:   none
Applies to:  all elements
Inherited:  see Inheritance of Painting Properties below
Percentages:  N/A
Media:  visual
none
(Same meaning as with 'fill'.)
currentColor
(Same meaning as with 'fill'.)
<color>
(Same meaning as with 'fill'.)
<uri> [ none | currentColor | <color> [icc-color(<colorvalue>*)] | inherit ]
(Same meaning as with 'fill'.)
'stroke-width'
Value:   <width> | inherit
Initial:   1
Applies to:  all elements
Inherited:  yes
Percentages:  Yes
Media:  visual
<width>
The width of the stroke on the current object, either expressed as a <length> in user units, a <length> in Transformed CSS units (??? add link) or as a percentage. If a percentage is used, the <width> is expressed as a percentage of the current viewport (??? add link).
'stroke-linecap'
Value:   butt | round | square | inherit
Initial:   butt
Applies to:  all elements
Inherited:  yes
Percentages:  N/A
Media:  visual

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

butt
See drawing below.
round
See drawing below.
square
See drawing below.

(??? insert drawing here)

'stroke-linejoin'
Value:   miter | round | bevel | inherit
Initial:   miter
Applies to:  all elements
Inherited:  yes
Percentages:  N/A
Media:  visual

'stroke-linejoin' specifies the shape to be used at the corners of paths (or other vector shapes) that are stroked. when they are stroked.

miter
See drawing below.
round
See drawing below.
bevel
See drawing below.

(??? insert drawing here)

'stroke-miterlimit'
Value:   <miterlimit> | inherit
Initial:   8
Applies to:  all elements
Inherited:  yes
Percentages:  N/A
Media:  visual

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-linewidth'.

<miterlimit>
The limit on the ratio of the miter length to the 'stroke-linewidth'. The value of <miterlimit> must be a number greater than or equal to 1.

(??? insert drawing here)

'stroke-dasharray'
Value:   none | <dasharray> | inherit
Initial:   none
Applies to:  all elements
Inherited:  yes
Percentages:  Yes. See below.
Media:  visual

'stroke-dasharray' controls the pattern of dashes and gaps used to stroke paths. <dasharray> should contain a list of space- or comma-separated numbers that specify the lengths of alternating dashes and gaps in user units. If an odd number of values is provided, then the list of values is 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.

none
Indicates that no dashing should be used. If stroked, the line should be drawn solid.
<dasharray>
A list of space- or comma-separated <length>'s which can be in user units or in any of the CSS units, including percentages. A percentage represents a distance as a percentage of the current viewport. (See Processing rules for CSS units and percentages.)

(??? insert drawing here)

'stroke-dashoffset'
Value:   <dashoffset> | inherit
Initial:   0
Applies to:  all elements
Inherited:  yes
Percentages:  Yes. See below.
Media:  visual

'stroke-dashoffset' specifies the distance into the dash pattern to start the dash.

<dashoffset>
A <length> which can be in user units or in any of the CSS units, including percentages. A percentage represents a distance as a percentage of the current viewport (??? Add link here).

(??? insert drawing here)

'stroke-opacity'
Value:   <opacity-value> | inherit
Initial:   100%
Applies to:  all elements
Inherited:  yes
Percentages:  Allowed
Media:  visual

'stroke-opacity' specifies the opacity of the painting operation used to stroke the current object. (??? Add link about how different opacity parameters interact.)

<opacity-value>
The opacity of the painting operation used to stroke the current object. If a <number> is provided, then it must be in the range of 0.0 (fully transparent) to 1.0 (fully opaque). If a percentage is provided, then it must be in the range of 0% to 100%. Any values outside of the acceptable range are rounded to the nearest acceptable value.
'stroke-params'
Value:   <string> | inherit
Initial:   Empty string
Applies to:  all elements
Inherited:  yes
Percentages:  Paint server-specific.
Media:  visual

'stroke-params' specifies an arbitrary <string> which is passed to the current stroke paint server. The meaning of <string> is paint server-specific. None of the built-in paint servers use 'stroke-params'. It is meant as a way to pass parameters to a custom paint servers defined via paint server extensibility.

<string>
A <string> containing parameters which should be passed to the current stroke paint server.

8.4 Markers

8.4.1 Introduction

To use a marker symbol for arrowheads or polymarkers, you need to define a <marker> element which defines the marker symbol and then refer to that <marker> element using the various marker properties (i.e., 'marker-start', 'marker-end', 'marker-mid' or 'marker') on the given <path> element or vector graphic shape. Here is an example which draws a triangular marker symbol that is drawn as an arrowhead at the end of a path:

<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG July 1999//EN" 
  "http://www.w3.org/Graphics/SVG/svg-19990730.dtd">
<svg width="4in" height="4in" 
     fitBoxToViewport="0 0 4000 4000" >
  <defs>
    <marker id="Triangle"
      fitBoxToViewport="0 0 10 10" ref-x="0" ref-y="5" 
      markerWidth="1.25" markerHeight="1.75"
      orient="auto">
      <path d="M 0 0 L 10 5 L 0 10 z" />
    </marker>
  </defs>
  <desc>Placing an arrowhead at the end of a path.
  </desc>
  <path d="M 1000 1000 L 2000 1000 L 3000 2000"
        style="fill:none; stroke:black; stroke-width:100; 
        marker-end:url(#Triangle)" />
</svg>

Download this example

8.4.2 The <marker> element

The <marker> element defines the graphics that is to be used for drawing arrowheads or polymarkers on a given <path> element or vector graphic shape.
 
<!ELEMENT marker (defs?,desc?,title?,
                  (path|text|rect|circle|ellipse|line|polyline|polygon|
                   use|image|svg|g|switch|a)*)>
<!ATTLIST marker
  id ID #IMPLIED
  xml:lang NMTOKEN #IMPLIED
  xml:space (default|preserve) #IMPLIED
  class NMTOKENS #IMPLIED
  style CDATA #IMPLIED
  refX CDATA #IMPLIED
  refY CDATA #IMPLIED
  fitBoxToViewport CDATA #IMPLIED
  preserveAspectRatio CDATA 'xmid-ymid meet'
  markerUnits (stroke-width | userSpace) "stroke-width"
  markerWidth  CDATA "3"
  markerHeight CDATA "3"
  orient CDATA "0">

Attribute definitions:

markerUnits = "strokeWidth | userSpace"
markerUnits indicates how to interpret the values of markerWidth and markerHeight (described as follows). If markerUnits="userSpace", then markerWidth and markerHeight represent values in the user coordinate system in place for the graphic object referencing the marker. If markerUnits="stroke-width", then markerWidth and markerHeight represent scale factors relative to the stroke width in place for graphic object referencing the marker.
markerWidth = "length"
Represents the width of the temporary viewport that is to be created when drawing the marker. Default value is "3".
markerHeight = "length"
Represents the height of the temporary viewport that is to be created when drawing the marker. Default value is "3".
orient = "auto | <angle>"
Indicates how the marker should be rotated. A value of auto indicates that the marker should be oriented such that its positive X-axis is pointing in a direction that is the average of the ending direction of path segment going into the vertex and the starting direction of the path segment going out of the vertex. (Refer to <path> element implementation notes for a more thorough discussion directionality of path segments.) A value of <angle> represents a particular orient in the user space of the graphic object referencing the marker. For example, if a value of "0" is given, then the marker will be drawn such that its X-axis will align with the X-axis of the user space of the graphic object referencing the marker. The default value is an angle of zero degrees.

Attributes defined elsewhere:
id, xml:lang, xml:space, class, style, refX, refY, fitBoxToViewport, preserveAspectRatio.

Markers are drawn such that their reference point (i.e., attributes ref-x and ref-y) is positioned at the given vertex.

8.4.3 Marker properties

'marker-start' defines the arrowhead or polymarker that should be drawn at the first vertex of the given <path> element or vector graphic shape. 'marker-end' defines the arrowhead or polymarker that should be drawn at the final vertex. 'marker-mid' defines the arrowhead or polymarker that should be drawn at every other vertex (i.e., every vertex except the first and last).

'marker-start', 'marker-end', marker-mid'
Value:   none |
inherit |
<uri>
Initial:   none
Applies to:  all elements
Inherited:  see Inheritance of Painting Properties below
Percentages:  N/A
Media:  visual
none
Indicates that no marker symbol should be drawn at the given vertex (vertices).
<uri>
The <uri> is an XPointer (???) reference to the ID of a <marker> element which should be used as the arrowhead symbol or polymarker at the given vertex (vertices). If the XPointer is not valid (e.g., it points to an object that is undefined or the object is not a <marker> element), then the marker(s) should not be drawn.

The 'marker' property specifies the marker symbol that should be used for all points on the sets the value for all vertices on the given <path> element or vector graphic shape. It is a short-hand for the three individual marker properties:

'marker'
Value:   see individual properties
Initial:   see individual properties
Applies to:  all elements
Inherited:  see Inheritance of Painting Properties below
Percentages:  N/A
Media:  visual

8.4.4 Details on How Markers are Rendered

The following provides details on how markers are rendered:

For illustrative purposes, we'll repeat the marker example shown earlier:
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG July 1999//EN" 
  "http://www.w3.org/Graphics/SVG/svg-19990730.dtd">
<svg width="4in" height="4in" 
     fitBoxToViewport="0 0 4000 4000" >
  <defs>
    <marker id="Triangle"
      fitBoxToViewport="0 0 10 10" ref-x="0" ref-y="5" 
      markerWidth="1.25" markerHeight="1.75"
      orient="auto">
      <path d="M 0 0 L 10 5 L 0 10 z" />
    </marker>
  </defs>
  <desc>Placing an arrowhead at the end of a path.
  </desc>
  <path d="M 1000 1000 L 2000 1000 L 3000 2000"
        style="fill:none; stroke:black; stroke-width:100; 
        marker-end:url(#Triangle)" />
</svg>

Download this example

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

<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG July 1999//EN" 
  "http://www.w3.org/Graphics/SVG/svg-19990730.dtd">
<svg width="4in" height="4in" 
     fitBoxToViewport="0 0 4000 4000" >
  <defs>
    <!-- Note: to illustrate the effect of "marker",
      replace "marker" with "symbol" and remove the various 
      marker-specific attributes -->
    <symbol id="Triangle"
      fitBoxToViewport="0 0 10 10" ref-x="0" ref-y="5">
      <path d="M 0 0 L 10 5 L 0 10 z" />
    </symbol>
  </defs>
  <desc>File which produces the same effect
      as the marker example file, but without
      using markers.
  </desc>
  <!-- The path draws as before, but without the marker properties -->
  <path d="M 1000 1000 L 2000 1000 L 3000 2000"
        style="fill:none; stroke:black; stroke-width:100" />

  <!-- The following logic simulates drawing a marker 
       at final vertex of the path. -->

  <!-- First off, move the origin of the user coordinate system
       so that the origin is now aligned with the end point of the path. -->
  <g transform="translate(3000 2000)" >

    <!-- Now, rotate the coordinate system 45 degrees because
         the marker specified orient="auto" and the final segment
         of the path is going in the direction of 45 degrees. -->
    <g transform="rotate(45)" >

      <!-- Establish a new viewport with an <svg> element.
           The width/height of the viewport are 1.25 and 1.75 times
           the current stroke-width, respectively. Since the
           current stroke-width is 100, the viewport's width/height
           is 125 by 175. Apply the fitBoxToViewport attribute
           from the <marker> element onto this <svg> element.
           Transform the marker symbol to align (ref-x,ref-y) with
           the origin of the viewport. -->
      <svg width="125" height="175" 
           fitBoxToViewport="0 0 10 10"
           transform="translate(0,-5)" >

        <!-- Expand out the contents of the <marker> element. -->
        <path d="M 0 0 L 10 5 L 0 10 z" />
      </svg>
    </g>
  </g>
</svg>

Download this example

8.5 Rendering Properties

The creator of an SVG document 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:   default | optimizeSpeed | crispEdges |
geometricPrecision | inherit
Initial:   false
Applies to:  all elements
Inherited:  yes
Percentages:  N/A
Media:  visual
default
Indicates that the user agent should 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 should 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 should 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 should emphasize geometric precision over speed and crisp edges.

The creator of an SVG document 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:   default | optimizeSpeed | optimizeLegibility |
geometricPrecision | inherit
Initial:   default
Applies to:   <text> elements
Inherited:   yes
Percentages:   yes
Media:   visual
default
Indicates that the user agent should 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 should 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 should 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 should 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.

The creator of an SVG document 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:   default | optimizeSpeed | optimizeQuality | inherit
Initial:   default
Applies to:  images
Inherited:  yes
Percentages:  N/A
Media:  visual
default
Indicates that the user agent should make appropriate tradeoffs to balance speed and quality, but quality should be given more importance than speed.
optimizeSpeed
Indicates that the user agent should emphasize rendering speed over quality. This option will sometimes cause the user agent to use a bilinear image resampling algorithm.
optimizeQuality
Indicates that the user agent should emphasize quality over rendering speed. This option will sometimes cause the user agent to use a bicubic image resampling algorithm.

The 'visibility' indicates whether a given object should be rendered at all.

'visibility'
Value:   visible | hidden | inherit
Initial:   visible
Applies to:  all elements
Inherited:  yes
Percentages:  N/A
Media:  visual
visible
The current object should be drawn.
hidden
The current object should not be drawn.

8.6 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 leaf-node individually, never at the <g> level. Thus, for the following SVG, two distinct gradients are painted (one for each rectangle):

<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG July 1999//EN" 
  "http://www.w3.org/Graphics/SVG/svg-19990730.dtd">
<svg width="4in" height="3in">
  <desc>Gradients apply to leaf nodes
  </desc>
  <g>
    <defs>
      <linearGradient id="MyGradient">
        <stop offset="0%" style="color:#F60"/>
        <stop offset="70%" style="color:#FF6"/>
      </linearGradient>
    </defs>
    <g style="fill: url(#MyGradient)">
      <rect width="20" height="15.8"/>
      <rect width="35" height="8"/>
   </g>
  </g>
</svg>

Download this example