For all media, the term *canvas* describes "the space where the
SVG document is rendered." The canvas is infinite for each dimension
of the space, but rendering occurs relative to a finite rectangular region
of the canvas. This finite rectangular region is called the **viewport**.
For visual media, the viewport is the viewing area where the user
sees the SVG document.

The size of the viewport (i.e., its width and height) is determined by a negotiation process (see Establishing the size of the initial viewport) between the SVG document and its parent (real or implicit). Once that negotiation process is completed, the SVG user agent is provided the following information:

- an integer value that represents the width of the viewport in "pixels"
- an integer value that represents the height of the viewport in "pixels"
- (highly desirable but not required) a real number value that indicates how many millimeters a "pixel" represents

Using the above information, the SVG user agent establishes an initial
**current coordinate system**
for the SVG document such that the origin of the current coordinate system
matches the origin of the viewport, and one unit in the current coordinate
system equals one "pixel" in the viewport. This initial
current coordinate system defines the initial **viewport space**
and the initial **user space** (also called
**user coordinate system**).

Lengths in SVG can be specified as:

- (if no unit designator is provided) values in user space -- for example, "15"
- (if a CSS unit specifier is provided) a length in CSS units -- for example, "15mm"

The supported CSS length unit specifiers are: em, ex, px, pt, pc, cm, mm, in, and percentages.

A new user space (i.e., a new current coordinate system) can be established
at any place in the SVG document
by specifying **transformations** in the form of
**transformation matrices** or simple transformation operations
such as rotation, skewing, scaling and translation.
Establishing new user spaces
via transformation operations are fundamental operations to 2D graphics
and represent the typical way of controlling the size, position, rotation and
skew of graphic objects.

New viewports also can be established, but are for more specialized uses. By establishing a new viewport, you can redefine the meaning of some of the various CSS unit specifiers (px, pt, pc, cm, mm, in, and percentages) and provide a new reference rectangle for "fitting" a graphic into a particular rectangular area. ("Fit" means that a given graphic is transformed in such a way that its bounding box in user space aligns exactly with the edges of a given viewport.)

The attributes of the initial viewport are established by either the CSS positioning
parameters that are defined by the outermost **<svg>** element
in combination with
the **width=** and **height=** XML attributes
that are required on the
**<svg>** element.

The size (i.e., width and height) of the initial viewport into which
an SVG document should be rendered
is determined as follows. If the outermost **<svg>** element
contains CSS positioning properties which establish the width
for the viewport, then the width of the viewport should be set to that size.
If the CSS positioning properties on the outermost **<svg>** element
do not provide sufficient information to determine the width of the viewport,
then the XML attributes **width=** determines the
width of the viewport.
Similarly, if the outermost **<svg>** element
contains CSS positioning properties which establish the height
for the viewport, then the height of the viewport should be set to that size.
If the CSS positioning properties on the **<svg>** element
do not provide sufficient information to determine the height of the viewport,
then the XML attributes **height=** determines the
height of the viewport.

In the following example, an SVG graphic is embedded within
a parent XML document which is formatted using CSS layout rules.
The **width="100px"** and **height="200px"** attributes are
used to set the size of the viewport:

<?xml version="1.0" standalone="yes"?> <parent xmlns="http://some.url"> <!-- SVG graphic --> <svg xmlns='http://www.w3.org/Graphics/SVG/svg-19990625.dtd' width="100px" height="200px"> <path d="M100,100 Q200,400,300,100"/> <!-- rest of SVG graphic would go here --> </svg> </parent>

The initial clipping path for an SVG document is determined by the
actual values
of the
**'clip'** and
**'overflow'**
properties that apply to the outermost **<svg>** element.
(These concepts and properties are defined in the Cascading Style Sheets, level 2
CSS2 Specification.)

To change the current user space coordinate system, you define
a **transformation** which defines how to transform coordinates
from the new user coordinate system into the previous user
coordinate system. Mathematically, the transformation is represented
by a **transformation matrix** which maps coordinates in the new
user coordinate system into the previous user coordinate system.
To illustrate:

(Insert an image which shows this concept.)

Transformation matrices define the mathematical mapping
from one coordinate space into another. Of particular interest is
the **current transformation matrix** (CTM) which
defines the mapping from user space into viewport space.

(Insert an image showing the CTM mapping user space into device space.)

Transformation matrices are specified as 3x3 matrices of the following form:

(Insert an image showing [a b 0 c d 0 e f 1], but as a rectangular matrix.)

Because SVG's transformation matrices only have six entries that can
be changed, these matrices will be called **2x3 transformation matrices**,
which for convenience are often written as an array of six numbers:
*[a b c d e f]*.

All coordinates in user space are expressed as (x,y) values. To calculate the transformation from the current user space coordinate system into viewport space, you multiply the vector (x,y,1) by the current transformation matrix (CTM) to yield (x',y',1):

(Insert an image showing [x',y',1]=[x,y,1][a b 0 c d 0 e f 1])

Whenever a new transformation is provided, a new CTM is calculated by the following formula. Note that the new transformation is pre-multiplied to the CTM:

(Insert an image which shows newCTM[a b c d e f]=[transformmatrix]*oldCTM[a b c d e f].)

It is important to understand the following key points regarding transformations in SVG:

- Transformations alter coordinate systems, not objects. All objects defined outside the scope of a transformation are unchanged by the transformation. All objects defined within the scope of a transformation will be drawn in the transformed coordinate system.
- Transformations specify how to map the transformed (new) coordinate system to the untransformed (old) coordinate system. All coordinates used within the scope the transformation are specified in the transformed coordinate system.
- Transformations are always premultiplied to the CTM.
- Matrix operations are not commutative - the order in which transformations
are specified is significant. For example, a translation followed by a rotation
will yield different results than a rotation followed by a translation:
(Insert an image illustrates the above concept.)

Mathematically, all transformations can be expressed as matrices. To illustrate:

- Translations are represented as [1 0 0 1 tx ty], where
*tx*and*ty*are the distances to translate the origin of the coordinate system in*x*and*y*, respectively. - Scaling is obtained by [sx 0 0 sy 0 0]. This scales the coordinates
so that one unit in the
*x*and*y*directions of the new coordinate system is the same as*sx*and*sy*units in the previous coordinate system, respectively. - Rotations are carried out by [cos(angle) sin(angle) -sin(angle) cos(angle) 0 0],
which has the effect of rotating the coordinate system axes by
*angle*degrees counterclockwise. - (Similar examples can be given for skew, reflect and other simple transformations. At this time, the SVG working group is still investigating these other simple transformations.)

(Insert an image illustrates the above concept.)

Various SVG elements have the effect of establishing a new viewport:

- Any
**<svg>**element establishes a new viewport - Any
**<use>**element establishes a temporary new viewport for drawing instances of predefined graphics objects - Markers establish a temporary new viewport for drawing arrowheads and polymarkers
- When the text on a path facility tries to draw a referenced <symbol> or <svg> element, it establishes a new temporary new viewport for the referenced graphic.
- When patterns are used to fill or stroke an object, a temporary new viewport is established for each drawn instance of the pattern.

<?xml version="1.0" standalone="no"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG June 1999//EN" "http://www.w3.org/Graphics/SVG/svg-19990625.dtd"> <svg width="4in" height="3in" fit-box-to-viewport"0 0 40 30"> <desc>This SVG drawing uses the fit-box-to-viewport attribute to automatically create an initial user coordinate system which causes the graphic to scale to fit into the viewport no matter what size the viewport is. </desc> <!-- This rectangle goes from (0,0) to (40,30) in user space. Because of the fit-box-to-viewport attribute above, the rectangle will end up filling the entire area reserved for the SVG document. --> <rect x="0" y="0" width="40" height="30" style="fill: blue" /> </svg>

In some cases, it is necessary that the aspect ratio of the graphic be retained
when utilizing **fit-box-to-viewport**.
A supplemental attribute **preserve-aspect-ratio="<align> [<meet-or-slice>]"** indicates whether or not
to preserve the aspect ratio of the original graphic. The **<align>** parameter indicates whether to preserve
aspect ratio and what alignment method should be used if aspect ratio is preserved.
The **<align>** parameter must be one of the following strings:

**none**(the default) - Do not attempt to preserve aspect ratio. Scale the graphic non-uniformly if necessary such that the graphic's bounding box exactly matches the viewport rectangle.**xmin-ymin**- Attempt to preserve aspect ratio. Align the smallest X value of the graphic's bounding box with the smallest X value of the viewport. Align the smallest Y value of the graphic's bounding box with the smallest Y value of the viewport.**xmid-ymin**- Attempt to preserve aspect ratio. Align the midpoint X value of the graphic's bounding box with the midpoint X value of the viewport. Align the smallest Y value of the graphic's bounding box with the smallest Y value of the viewport.**xmax-ymin**- Attempt to preserve aspect ratio. Align the maximum X value of the graphic's bounding box with the maximum X value of the viewport. Align the smallest Y value of the graphic's bounding box with the smallest Y value of the viewport.**xmin-ymid**- Attempt to preserve aspect ratio. Align the smallest X value of the graphic's bounding box with the smallest X value of the viewport. Align the midpoint Y value of the graphic's bounding box with the midpoint Y value of the viewport.**xmid-ymid**- Attempt to preserve aspect ratio. Align the midpoint X value of the graphic's bounding box with the midpoint X value of the viewport. Align the midpoint Y value of the graphic's bounding box with the midpoint Y value of the viewport.**xmax-ymid**- Attempt to preserve aspect ratio. Align the maximum X value of the graphic's bounding box with the maximum X value of the viewport. Align the midpoint Y value of the graphic's bounding box with the midpoint Y value of the viewport.**xmin-ymax**- Attempt to preserve aspect ratio. Align the smallest X value of the graphic's bounding box with the smallest X value of the viewport. Align the maximum Y value of the graphic's bounding box with the maximum Y value of the viewport.**xmid-ymax**- Attempt to preserve aspect ratio. Align the midpoint X value of the graphic's bounding box with the midpoint X value of the viewport. Align the maximum Y value of the graphic's bounding box with the maximum Y value of the viewport.**xmax-ymax**- Attempt to preserve aspect ratio. Align the maximum X value of the graphic's bounding box with the maximum X value of the viewport. Align the maximum Y value of the graphic's bounding box with the maximum Y value of the viewport.

The **<meet-or-slice>** parameter is optional
and must be one of the following strings:

**meet**(the default) - Scale the graphic such that:- aspect ratio is preserved
- the entire graphic (as defined by its bounding box) is visible within the viewport
- the graphic is scaled up as much as possible, while still meeting the other criteria

**slice**- Scale the graphic such that:- aspect ratio is preserved
- the entire viewport is covered by the graphic (as defined by its bounding box)
- the graphic is scaled down as much as possible, while still meeting the other criteria

All modifications to the user coordinate system are specified with the **transform** attribute:
The **transform** attribute defines a new coordinate system transformation
and thus implicitly a new user space and a new CTM. A transform attribute takes a list
of transformations, which are applied in the order provided. The available transformations
include:

**matrix(<a> <b> <c> <d> <e> <f>)**, which specifies that the given transformation matrix should be premultiplied to the old CTM to yield a new CTM.

**translate(<tx> [<ty>])**, which indicates that the origin of the current user coordinate system should be translated by*tx*and*ty*If*<ty>*is not provided, it is assumed to be zero.

[A translate is equivalent to**matrix(1 0 0 1 tx ty)**].

**scale(<sx> [<sy>])**, which indicates that the user coordinate system should be scaled by*sx*and*sy*. If*<sy>*is not provided, it is assumed to be equal to*<sy>*.

[A scale is equivalent to**matrix(sx 0 0 sy 0 0)**].

**rotate(<rotate-angle>)**, which indicates that the current user coordinate system should be rotated relative to its origin by <rotate-angle>, which is expressed in degrees.

[A rotation is equivalent to**matrix(cos(angle) sin(angle) -sin(angle) cos(angle) 0 0)**].

**skew-x(<skew-angle>)**, which indicates that the current user coordinate system should be transformed such that, for positive values of <skew-angle>, increasingly positive Y values will be tilted by increasing amounts in the direction of the positive X-axis. (??? Need picture). <skew-angle> is expressed in degrees.

[A skew-x is equivalent to**matrix(1 0 tan(angle) 1 0 0)**].

**skew-y(<skew-angle>)**, which indicates that the current user coordinate system should be transformed such that, for positive values of <skew-angle>, increasingly positive X values will be tilted by increasing amounts in the direction of the positive Y-axis. (??? Need picture). <skew-angle> is expressed in degrees.

[A skew-y is equivalent to**matrix(1 tan(angle) 0 1 0 0)**].

All values are real numbers.

If a list of transforms is provided, then the net effect is as if each transform
had been applied separately in the order provided. For example,
**transform="translate(-10,-20) scale(2) rotate(45) translate(5,10)"**
indicates that:

- the origin of the user coordinate system should be translated -10 units in X and -20 units in Y (equivalent to transformation matrix [1 0 0 1 -10 -20]),
- then the user coordinate system should be scaled uniformly by a factor of 2 (equivalent to transformation matrix [2 0 0 2 0 0]),
- then the user coordinate system should be rotated by 45 degrees (equivalent to transformation matrix [cos(45) sin(45) -sin(45) cos(45)]),
- then origin of the user coordinate system should be translated by 5 units in X and 10 units in Y (equivalent to transformation matrix [1 0 0 1 5 10]).

The **transform** attribute is applied to an element before processing any
other coordinate or length values supplied for that element. Thus, in the
element ** <rect x="10" y="10" width="20" height="20" transform="scale(2)" />**,
the x, y, width and height values are processed after the current coordinate system
has been scaled uniformly by a factor of 2 by the

At any point in an SVG drawing, you can establish a new viewport
into which all contained graphics should be drawn by including
an **<svg>** element inside an SVG document. By establishing
a new viewport, you also implicitly establish a new initial user space,
new meanings for many of the CSS unit specifiers
and, potentially, a new clipping path.

To establish a new viewport, you use the positioning properties
from CSS such as **left:**, **top:**,
**right:**, **bottom:**,
**width:**, **height:**, margin properties
and padding properties. Here is an example:

<?xml version="1.0" standalone="no"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG June 1999//EN" "http://www.w3.org/Graphics/SVG/svg-19990625.dtd"> <svg width="4in" height="3in"> <desc>This SVG drawing embeds another one, thus establishing a new viewport </desc> <!-- The following statement establishing a new viewport and renders SVG drawing B into that viewport --> <svg style="left: 25%; top: 25%" width="50%" height="50%"> <!-- drawing B goes here --> </svg> </svg>

You can also specify values for the **'clip'** and **'overflow'**
properties for <svg> elements within an SVG document. If specified on an <svg> element,
these properties will change
the current clipping path. (Note that these properties will be ignored if used on
any other type of element.)

(Extract sections from chapter 8 of the CSS spec. Make modifications as necessary.).

All coordinates and lengths in SVG can be specified in one of the following ways:

**User units**. If no unit specifier is provided, a given coordinate or length is assumed to be in user units (i.e., a value in user space). For example:<text style="font-size: 50">Text size is 50 user units</text>

**CSS units**. If a unit designator is provided on a coordinate or length value, then the given value is assumed to be in CSS units. Available unit designators are the absolute and relative unit designators from CSS (em, ex, px, pt, cm, mm, in and percentages). As in CSS, the*em*and*ex*unit designators are relative to the current font's*font-size*and*x-height*, respectively. Initially, the various absolute unit specifiers from CSS (i.e., px, pt, cm, mm, in) represent lengths within the initial user coordinate system and do not change their meaning as transformations alter the current coordinate system. Thus, "12pt" can be made to represent exactly 12 points on the actual visual medium even if the user coordinate system has been scaled. For example:<?xml version="1.0" standalone="no"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG June 1999//EN" "http://www.w3.org/Graphics/SVG/svg-19990625.dtd"> <svg width="4in" height="3in"> <desc>Demonstration of coordinate transforms </desc> <!-- The following two text elements will both draw with a font height of 12 pixels --> <text style="font-size: 12">This prints 12 pixels high.</text> <text style="font-size: 12px">This prints 12 pixels high.</text> <!-- Now scale the coordinate system by 2. --> <g style="transform: scale(2)"> <!-- The following text will actually draw 24 pixels high because each unit in the new coordinate system equals 2 units in the previous coordinate system. --> <text style="font-size: 12">This prints 24 pixels high.</text> <!-- The following text will actually still draw 12 pixels high because the CSS unit specifier has been provided. --> <text style="font-size: 12px">This prints 12 pixels high.</text> </g> </svg>

If possible, the SVG user agent should be passed the actual size of a *px* unit in inches or
millimeters by its parent user agent. (See Conformance Requirements and Recommendations.)
If such information is not available from the parent user agent,
then the SVG user agent should assume a *px* is defined to be exactly .28mm.

The process of establishing a new viewport
via an **<svg>** element inside of an SVG document
changes the meaning
of the following CSS unit specifiers: px, pt, cm, mm, in, and % (percentages).
A "pixel" (the px unit) becomes equivalent to a single unit in the user
coordinate system for the given **<svg>** element.
The meaning of the other absolute unit specifiers (pt, cm, mm, in) are
determined as an appropriate multiple of a *px* unit using the actual size of
*px* unit (as passed from the parent user agent to the SVG user agent).
Any percentage values that are relative to the current viewport will also
represent new values.

<?xml version="1.0" standalone="no"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG June 1999//EN" "http://www.w3.org/Graphics/SVG/svg-19990625.dtd"> <svg width="300px" height="3oopx"> <desc>Transformation with establishment of a new viewport </desc> <!-- The following two text elements will both draw with a font height of 12 pixels --> <text style="font-size: 12">This prints 12 pixels high.</text> <text style="font-size: 12px">This prints 12 pixels high.</text> <!-- Now scale the coordinate system by 2. --> <g style="transform: scale(2)"> <!-- The following text will actually draw 24 pixels high because each unit in the new coordinate system equals 2 units in the previous coordinate system. --> <text style="font-size: 12">This prints 24 pixels high.</text> <!-- The following text will actually still draw 12 pixels high because the CSS unit specifier has been provided. --> <text style="font-size: 12px">This prints 12 pixels high.</text> </g> <!-- This time, scale the coordinate system by 3. --> <g style="transform: scale(3)"> <!-- Establish a new viewport and thus change the meaning of some CSS unit specifiers. --> <svg style="left:0; top:0; right:100; bottom:100" width="100%" height="100%"> <!-- The following two text elements will both draw with a font height of 36 screen pixels. The first text element defines its height in user coordinates, which have been scaled by 3. The second text element defines its height in CSS px units, which have been redefined to be three times as big as screen pixels due the <svg> element establishing a new viewport. --> <text style="font-size: 12">This prints 36 pixels high.</text> <text style="font-size: 12px">This prints 36 pixels high.</text> </svg> </g> </svg>

(Include an example which shows multiple viewports, multiple user spaces and multiple use of different units.)

Any values expressed in CSS units or percentages of the current viewport should be implemented such that these values map to corresponding values in user space as follows:

- Coordinate values:
- If both X and Y are expressed in viewport-relative coordinates
(e.g.,
**<rect x="3in" y="2in" ... />**), then convert from CSS units into viewport space so that you have a coordinate pair (X,Y) in viewport space. Then apply the inverse of the current transformation matrix (CTM) onto (X,Y) to provide an (X',Y') coordinate value in user space. - If X is expressed in viewport-relative units, but Y is expressed in
user space units (e.g., in
**<rect x="2in" y="15" ... />**, X is expressed in viewport-relative units but Y is expressed in user space units), then determine the equation of the line in user space which corresponds to the vertical line through the point (X,0) in viewport space. (If user space is rotated or skewed relative to the viewport, then the line in user space will no longer be vertical.) Then the result point (X',Y') in user space that you want is the intersection of the above equation with the horizontal line through the point (0,Y) in user space.

As a example, suppose your viewport is 10 cm wide and 10 cm high and the CTM is [ 10 0 0 10 0 0 ]. If you encounter**<rect x="5cm" y="1" ... />**, then determine the equation of the line in user space that goes through (5cm, 0) in viewport space (the equation is`x = .5`

). The result point (X',Y') in user space is the intersection of the line`x = .5`

with the line`y = 1`

, which results in the point`(X',Y')=(.5,1)`

in user space. - If Y is expressed in viewport-relative units, but X is expressed in
user space units (e.g., in
**<rect x="43" y="2cm" ... />**, X is expressed in user space units but Y is expressed in viewport-relative units), then determine the equation of the line in user space which corresponds to the horizontal line through the point (0,Y) in viewport space. (If user space is rotated or skewed relative to the viewport, then the line in user space will no longer be vertical.) Then the result point (X',Y') in user space that you want is the intersection of the above equation with the horizontal line through the point (0,Y) in user space.

As a example, suppose your viewport is 10 cm wide and 10 cm high and the CTM is [ 10 0 0 10 0 0 ]. If you encounter**<rect x="1" y="5cm" ... />**, then determine the equation of the line in user space that goes through (0, 5cm) in viewport space (the equation is`y = .5`

). The result point (X',Y') in user space is the intersection of the line`y = .5`

with the line`x = 1`

, which results in the point`(X',Y')=(1,.5)`

in user space.

- If both X and Y are expressed in viewport-relative coordinates
(e.g.,
- For any width value represented in a viewport-relative coordinate system (i.e., CSS units or percentages), transform the points (0,0) and (width,0) from viewport space to current user space using the inverse of the current transformation matrix, yielding two points in userspace Q1 and Q2. Do a distance calculation between Q1 and Q2 (sqrt((Q2x-Q1x)**2,(Q2y-Q1y)**2)) and use that as the width value for the given operation.
- For any height value represented in a viewport-relative coordinate system (i.e., CSS units or percentages), do the same thing as above, but use points (0,0) and (0,height) instead.
- For any length value which isn't tied to an axis, we use an approach which gives appropriate weighting to the contribution of the two dimensions of the viewport. Determine an angle ang=atan(viewport-height/viewport-width), then determine a point P=(length*cos(ang), length*sin(ang)) in viewport space. Transform the two points (0,0) and P from viewport space into current userspace using the inverse of the current transformation matrix, yielding two points in userspace Q1 and Q2. Do a distance calculation between Q1 and Q2 (sqrt((Q2x-Q1x)**2,(Q2y-Q1y)**2)) and use that as the length value for the given operation.