This document is a submission to the World Wide Web Consortium. It is the initial draft of the specification of VML. It is intended for review and comment by W3C members and is subject to change. There are W3C Staff comments on this submission.
This document is a NOTE made available by the W3 Consortium for discussion only. This indicates no endorsement of its content, nor that the Consortium has, is, or will be allocating any resources to the issues addressed by the NOTE.
This document defines the Vector Markup Language (VML). VML is an application of Extensible Markup Language (XML) 1.0 which defines a format for the encoding of vector information together with additional markup to describe how that information may be displayed and edited. The first part of this document is an introduction, which gives an overview of the way VML is organized and how it interacts with both XML and HTML as defined by the HTML 4.0 Specification. This is followed by detailed technical definition of the behavior of every VML element and the permitted and recommended behaviors for all applications.
The introduction to this document is intended to be appropriate reading for someone who wishes to gain an overview of VML. The technical specification is intended for authors of application software which might use VML and for people who wish to assess the suitability of VML for a particular application. It may also be used by people who need to hand-author VML content. However it is anticipated that most such authoring will proceed by copy and paste of existing VML - VML is intended to be treated in this way.
shape
Element shapetype
Element group
Element background
Element path
Element formulas
Element handles
Element fill
Element stroke
Element shadow
Element textbox
Element textpath
Element imagedata
Element line
Element polyline
Element curve
Element roundrect
Element oval
Element arc
Element image
Element The Vector Markup Language (VML) supports the markup of vector graphic information in the same way that HTML supports the markup of textual information. Within VML the content is composed of paths described using connected lines and curves. The markup gives semantic and presentation information for the paths.
VML is written using the syntax of XML just as HTML is written using the syntax of SGML (the Standard Generalized Markup Language, [ISO 8879]) - XML is a restricted form of SGML. VML uses Cascading Style Sheets, Level 2 in the same way as HTML to determine the layout of the vector graphics which it contains. The workflow involved in rendering VML can be compared to that involved in rendering HTML as show in the following figure.
The primary difference between the HTML workflow and the VML workflow is in the last but one step - character layout versus path transformations. In the HTML case, the workflow generates locations and other information for sequences of characters which are then rendered using native operating system functionality. In the VML, case the workflow generates locations and related information for vector paths and related objects (such as bitmaps) which are then rendered using native operating system functionality.
The common workflow is an essential part of VML - two design requirements were to integrate VML with existing HTML and to avoid requiring a user agent to reinvent the wheel by using different representations or implementations of existing HTML or CSS functionality.
Like HTML, VML describes objects which will often be further edited. In the case of HTML, these objects are paragraphs, forms or tables. In the case of VML, the objects are shapes or collections of shapes known as groups. VML does not require a particular approach to editing - it accommodates a wide variety of editors. The enormous range of graphical data requires that VML pays careful attention to how an editor records the semantic information related to the VML description. VML ensures that different editors can recognize and correctly handle each other's data (even though they will not normally understand it).
The simple diagram below contains both simple graphics and text.
Although the bitmap compression used makes the image very small (it only requires about 8kbytes) the bitmap has none of the information necessary to make further changes to the diagram - for example a user who needs to change "Product" to "Products" must recreate the bitmap from scratch. The corresponding VML has all the necessary editing information in about 2.5kbytes.
.font5 { color: black; font-size: 18.0pt; font-weight: 400; font-style: normal; text-decoration: none; vertical-align: text-bottom; font-family: "Times New Roman"; }
<v:group style='position: absolute; margin-left: 10.2pt; margin-top: 4.8pt; width: 90pt; height: 191.4pt; z-index: 1' coordsize="21600, 21600">
<v:shapetype id="irregularSeal1" coordorigin="17, 8" coordsize="150, 319" path="m10800,5800l8352,2295,7312,6320,370,2295,4627,7617,,8615,3722,11775,135,14587, 5667,13937,4762,17617,7715,15627,8485,21600,10532,14935,13247,19737,14020, 14457,18145,18095,16837,12942,21600,13290,17607,10475,21097,8137,16702,7315, 18380,4457,14155,5325,14522,0xe"> <v:stroke joinstyle="miter"/> <v:path gradientshapeok="t" textboxrect="4627, 6320, 16702, 13937"/> </v:shapetype>
<v:shape type="#irregularSeal1" style='position: absolute; left: 17; top: 8; width: 150; height: 120' fillcolor="#f06"> <v:fill type="gradient" color2="fill lighten(0)" method="linear sigma" angle="-135" focus="100%"/> <v:textbox> <div> <span class="font5">Idea</span> </div> </v:textbox> </v:shape>
<v:shapetype id="downArrow" coordsize="21600, 21600" adj="16200, 5400" path="m0@0l@1@0@1,0@2,0@2@0,21600@0,10800,21600xe"> <v:stroke joinstyle="miter"/> <v:formulas> <v:f eqn="sum #0 0 0"/> <v:f eqn="sum #1 0 0"/> <v:f eqn="sum height 0 #1"/> <v:f eqn="sum 10800 0 #1"/> <v:f eqn="sum width 0 #0"/> <v:f eqn="prod @4 @3 10800"/> <v:f eqn="sum width 0 @5"/> </v:formulas> <v:path textboxrect="@1, 0, @2, @6"/> <v:handles> <v:h position="#1, #0" xrange="0, 10800" yrange="0, 21600"/> </v:handles> </v:shapetype>
<v:shape type="#downArrow" style='position: absolute; left: 40; top: 143; width: 105; height: 105' adj="11632, 4371" fillcolor="#6f9"> <v:fill type="gradientScale" color2="fill lighten(0)" method="linear sigma" angle="-135" focus="100%"/> </v:shape>
<v:shapetype id="flowChartTerminator" coordsize="21600, 21600" v="m3475,0qx0,10800qy3475,21600l18125,21600qx21600,10800qy18125,0xe"> <v:stroke joinstyle="miter"/> <v:path gradientshapeok="t" textboxrect="1018, 3163, 20582, 18437"/> </v:shapetype>
<v:shape type="#flowChartTerminator" style='position: absolute; left: 17; top: 263; width: 150; height: 64' fillcolor="#39f"> <v:fill type="gradient" color2="fill lighten(0)" method="linear sigma" angle="-135" focus="100%"/> <v:textbox> <div> <span class="font5">Product</span> </div> </v:textbox> </v:shape>
</v:group>
This VML contains all the information required both to edit and to display the diagram. The VML has been color coded as follows:
Blue - XML structure. VML is formatted according to the rules of XML. The v: prefix on each VML tag identifies the tag as VML, following the current suggestion for handling namespaces in XML. Any standard XML parser can parse the VML and hand off the resultant data to a VML specific processor.
Green - CSS information. The first block of CSS is
used in the HTML which defines the text in the diagram - this is just standard CSS.
Each shape
and group
element has a CSS style attribute which
defines the position and size of the shape within the page. The location of the
top-level group is defined completely by the CSS - a layout engine need not understand any
aspect of VML to handle this positioning information.
Black - VML. The remainder of the data describes the graphical properties of the
diagram. Notice how this data is associated with the shape
and shapetype
elements. The shape
elements are rendered in the diagram, the shapetype
elements allow reuse of geometric information between shapes. In this case, because
there are three different shapes in the diagram, there are also three shapetype
elements, but in more complex cases the same shape would be used multiple times (each
instance referencing the same shapetype
element).
Brown - HTML text. This text is associated with shape
elements in the diagram. The VML in italics controls the location of the
HTML text.
Purple - the most basic VML geometric information
describes closed or open paths. These paths may be parameterized - this allows a
single shapetype
element to define multiple related paths. For example,
the downArrow
shapetype above is defined parametrically and the following
four arrows all share the same basic shape.
The corresponding VML is:
<v:shape type="#downArrow" style='position: absolute; left: 77; top: 16; width: 64; height: 128' /> <v:shape type="#downArrow" style='position: absolute; left: 149; top: 16; width: 64; height: 128' adj=", 9450" /> <v:shape type="#downArrow" style='position: absolute; left: 219; top: 16; width: 64; height: 128' adj="14175, 2025" /> <v:shape type="#downArrow" style='position: absolute; left: 292; top: 16; width: 64; height: 128' adj="7088, 7425" />
The combination of parameterization with a concise path description allows VML diagrams to be relatively compact, despite the large amount of editing information. Indeed, large VML diagrams become dominated by the CSS required to position the elements. VML defines a defaulting mechanism for CSS which allows the container box to be inherited in order to avoid this overhead on complex illustrations.
Many requirements guided the design of VML. The most crucial are listed below in order of importance.
An implementation of VML will fall into one of two classes. A viewer implementation will normally implement the full specification, although it can avoid the need to implement any functionality to edit VML (beyond that required by any script language which the viewer supports). An editor implementation may only need to implement those specific features necessary to output the data which the editor manipulates. Even an editor which potentially manipulates VML produced by other applications may need nothing more than a subset of the CSS2 visual rendering model. Such an editor can correctly position the VML produced by other applications even though it may not be able to render individual shapes.
The implementation model follows the diagram at the start of this document. An implementation can proceed in five separate, independent, steps.
Each of these five steps is testable in isolation and implementable independently of the other steps. Only steps (2) and (4) are VML specific, and step (2) can reuse standard technology available in many places.
The overall structure of VML may be summarized by the XML definitions of the two
primary elements - shape
and group
.
A shape
element is used to define a visible vector graphic element.
Most shapes have a path definition - a sequence of straight lines and cubic
b騷ier curves which defines an outline. The outline may be stroked, as
specified by attributes on the shape and the stroke
sub-element. It may
also be filled, under the control of shape attributes and the fill
sub-element. Additional sub-elements support raster (bitmap) images, more advanced
transformations of the path and text drawn on top of the shape.
Below is an example of a simple shape and its VML representation.
[画像:A green five pointed star with a red outline.]
<v:shape style='top: 0; left: 0; width: 250; height: 250'
stroke="true"
strokecolor="red" strokeweight="2" fill="true"
fillcolor="green" coordorigin="0
0" coordsize="175 175">
<v:path v="m 8,65
l 72,65,92,11,112,65,174,65,122,100,142,155,92,121,42,155,60,100
x e"/>
</v:shape>
A group
element is used to group together several shapes so that they may
be transformed together as one unit.
In addition VML defines several auxiliary top-level elements to help make the editing and representation of complex graphical information more compact and convenient.
The shapetype
element is used to define a prototype definition of a shape.
A shape
element may reference a shapetype
in order to
instantiate several copies of the same shape.
Several predefined shapes may be used as convenient alternatives to explicitly
declaring a shape element with a path. These predefined shapes are line
,
polyline
, curve
, rect
, roundrect
, oval
,
arc
, and image
.
The style attribute uses the syntax described in "Visual rendering model" in Cascading Style Sheets, Level 2. The positioning may be absolute or relative unless the shape is within a group, in which case it must be absolute (relative to the top left of the parent group). The z order of the elements within the group is from the first (lowest) to the last (highest) - i.e. later elements obscure earlier elements. The elements establish no relative position - hence the restriction to use of absolute positioning.
The VML shape
and group
elements participate fully in the
CSS2 visual rendering model. In addition to standard CSS layout the VML elements may
also be rotated or flipped. Each element also establishes a coordinate space for its
content - this allows scaling of the content with respect to the containing elements.
The following VML specific CSS properties support this.
rotation
The value specifies a rotation for the shape or group in clockwise degrees about its center (i.e. positive is clockwise, negative is counterclockwise - the normal definition in an inverted coordinate space).
flip
The value specifies that the shape or group is flipped about its center about either the x or the y axis according to the following table.
Both x
and y
may be specified in the flip property.
center-x
, center-y
These properties may be used to specify the center of the block level box of the
element within its parent container box. They are alternatives to left
and right
and convey the same information. It is an error to specify
both left
and center-x
. A user agent should respond to the
error by honoring center-x
(or center-y
). The user agent
may issue a diagnostic to the user if this is appropriate.
The shape
and group
elements are containing blocks for their
content - they define a CSS2 "block level box". Inside the containing
block a local coordinate system is defined for any sub-elements using the coordsize
and coordorigin
attributes. All CSS2 positioning information is
expressed in terms of this local coordinate space. Consequently CSS2 position
attributes (left
, top
, width
, height
and so on) have no unit specifier - they are simple numbers, not CSS length quantities.
The coordsize
attribute defines how many units there are along the width
of the containing block. The coordorigin
attribute defines the coordinate at
the top left corner of the containing block. For example, if a group were defined as
follows:
<v:group style='width: 300px; height: 250px' coordsize="1000,1000"
coordorigin="-500,-500" />
The containing block would be 300 pixels wide by 250 pixels high (assume that the parent element of this group was not another group). Then the coordinate system inside the containing block would range from 500.0 to 500.0 along the x-axis and 500.0 to 500.0 along the y-axis with 0.0, 0.0 right in the center of the rectangle. Any shapes inside the group are positioned and sized according to this local coordinate system. No matter how the width and height of the group is changed, the local coordinate system inside will remain the same.
The rationale behind this is that the vectors defining a shape can be specified in a local coordinate system. If the containing block for the shape is changed, the outline of the shape will be automatically scaled to the new box. Similarly, shapes within the local ordinate system of a group will be automatically scaled if the containing block of the group changes.
It is important to note that the containing block does not establish a clipping region. Sub-elements and paths may be drawn outside the boundaries of the containing block. The containing block merely serves to map the local coordinate space to the page space.
Basic types of attributes are identified according to their lexical form as follows.
A complete set of data types is defined for VML along with canonical representations which ensure that the minimum precision which an authoring tool must store and the maximum which it can rely on are well defined. At this stage the tables in this document do not give the underlying data types.
VML shape elements (shape
and group
and the predefined
shapes) use the standard HTML core attributes plus some attributes which may appear on any
element.
<!entity %coreattrs
id id
#implied -- document-wide unique id --
class cdata #implied -- space separated
list of classes --
style cdata #implied -- associated style
info --
title cdata #implied -- advisory
title/amplification -
href cdata #implied -- URL link if
the element is clicked on --
target cdata #implied -- target frame for href
-
alt cdata #implied --
alternate text if element cannot be displayed --
coordsize cdata #implied - size of coordinate space inside
the element --
coordorigin cdata #implied -- coordinate at top-left corner of element --
wrapcoords cdata #implied -- outline to use for tight text wrapping --
>
In addition shape elements and the special pre-defined elements have standard
attributes to control rendering.
<!entity %shapeattrs
opacity cdata #implied -- opacity of the shape --
chromakey cdata #implied - color to be made transparent --
stroke cdata #implied -- Boolean whether to
stroke the outline or not --
strokecolor cdata #implied - RGB color to use for the stroke --
strokeweight cdata #implied - weight of the line to use for stroking --
fill cdata #implied -- Boolean
whether to fill the shape or not --
fillcolor cdata #implied - RGB color to use for the fill --
print cdata #implied -- Boolean whether
the element is to be printed --
>
Sub-elements are used within shape elements to define more sophisticated
rendering operations.
<!entity %shape.elements
(path | formulas | handles | fill | stroke | shadow | textbox | textpath |
imagedata |
%extensions;)
>
At most one instance of each sub-element may occur in a shape element. If multiple elements do occur the user agent should respond to the error by merging the repeated elements and retaining only the last values specified if the same attribute is specified more than once. The user agent may also issue a diagnostic if appropriate.
The entity %extensions;
acts as a placeholder for future extensions.
Any extension element may be qualified by the v:ext
attribute.
<!attlist (%extensions;)
v:ext cdata "backwardcompatible" -- may also be "view" or
"edit" --
>
When an authoring agent encounters such an element the v:ext
attribute
tells it how to handle the extension.
v:ext
value
Element interpretation
Viewer behavior
Editor behavior
edit
The element contains high level semantic information which was used by the original
content generator. The information should not be removed from the shape.
The element content can be ignored.
The element content can be ignored, it need not be removed however it must not be
duplicated.
backwardcompatible
The element contains information from the original content generator which does not
affect the appearance of the shape but which must be changed if the shape is changed.
The element content can be ignored.
The element content can be ignored unless the shape is edited, in which case the
element must be removed.
view
The element contains information which changes the appearance of the shape from that
implied by VML.
The element cannot be displayed, the viewer must use the alternate IMG
representation.
The element content can be ignored unless the shape is edited. The VML
information can be used as a placeholder.
These rules give an editor application the ability to edit any VML document. If
an editor just changes the document layout it can still handle even v:ext="view"
extensions - the VML definition ensures that the editor knows the CSS layout properties of
the shape. The rules accommodate a wide variety of editor behavior - an editor might
chose to lock an extended shape to prevent invalidation of the extension information for
example.
shape
Element This is the top-level element used to describe a shape. This element may appear by
itself or within a <group>
element. If a <shapetype>
is referenced using the type= attribute
, any attributes specified in the
shape will override those found in the shapetype
.
<!element shape (%shape.elements;)* >
<!attlist shape %coreattrs; %shapeattrs;
type cdata #implied -- reference to shapetype --
adj cdata #implied -- list of adjust values for parameterized paths --
path cdata #implied -- string with command set describing a path --
>
The path definition is described in more detail below. Path parameterization allows one canonical path to describe a range of shapes which differ only in geometric proportions (for example, ring shapes where the ratio of the inner to the outer circle diameter varies).
id
that describes the standard path, fill and
stroke properties of a shape. Properties specified in the shape will override the
shapetype properties.
hidden
the shape is not rendered and does not generate mouse events.
absolute
.
stroke
sub-element which may specify
more complex stroke properties. The stroke sub-element has an on
attribute
which will override this if specified.
path
element for more information. X or Y coordinate values can be a reference to a
formula in the form @
number where number is the formulas
ordinal number, e.g., "@
2". See the formula
element.
AREA
).
Describes in drawing units around a shape. Used for the tight wrapping of text around an
object.
Throughout this document XML templates are used to summarize the full set of
attributes which may appear on each element. The shape elements - shape
,
group
and most of the predefined shapes have CSS2 positioning information
which locates the shape within its container. This is not reflected in the templates
as there are several different ways of specifying the same information. A top-level
shape will typically use absolute
positioning plus margin-left
and margin-top
properties:
style='position: absolute; margin-left: 10pt; margin-top: 10pt; width: 100pt;
z-index: 1.5'
A shape within a group can use left
/top
or center-x
/center-y
as appropriate:
style='left: 100; top: 100; width: 1000; height: 1000'
style='center-x: 550; center-y: 550; width: 1000; height: 1000; rotation: 55deg'
The rotation
, z-index
and flip
properties may
also be given when required.
<shape
type=null
adj=null
path=null
opacity="100%"
chromakey="none"
stroke="true"
strokecolor="black"
strokeweight="0.75pt"
fill="true"
fillcolor="white"
print="true"
id=null
class=null
style='visibility: visible'
title=null
href=null
target=null
alt=null
coordsize="1000, 1000"
coordorigin="0, 0"
wrapcoords=null
/>
shapetype
Element This is the element used to describe a shape so that it may be referenced at a later
point in the document by a shape
element. It is identical to the shape
element except that it cannot reference another shapetype
element and that
the visibility
property is always hidden
. (Authoring
agents may choose to make shapetype
elements visible to allow them to be
edited - in this case the CSS positioning properties become relevant.)
When a shape
element makes reference to a shapetype
, the shape
may duplicate some of the attributes that have already been specified in the shapetype
.
In these cases, the attributes in the shape
override those of the shapetype.
<!element shapetype (%shape.elements;)* >
<!attlist shapetype %coreattrs; %shapeattrs;
adj cdata #implied -- list of adjust values for parameterized paths --
path cdata #implied -- string with command set describing a path --
>
See <shape>
.
<shapetype
adj=null
path=null
opacity="100%"
chromakey="none"
stroke="true"
strokecolor="black"
strokeweight="0.75pt"
fill="true"
fillcolor="white"
print="true"
id=null
class=null
style='visibility: visible'
title=null
href=null
target=null
alt=null
coordsize="1000, 1000"
coordorigin="0, 0"
wrapcoords=null
/>
group
Element This top-level element is used to group shapes (including other groups) so that they can be positioned and transformed as a single unit.
<!element group
(group | shape | shapetype | line | polyline | curve | rect | roundrect | oval |
arc | image)*
>
<!attlist group %coreattrs; >
See <shape>
for the descriptions of the following attributes: id
,
class
, style
(top
, left
, width
,
height
, rotation
, z-index
, position
, visibility
),
title
, href
, target
, alt
, coordsize
,
coordorigin
.
<group
id=null
class=null
style='visibility: visible'
title=null
href=null
target=null
alt=null
coordsize="1000, 1000"
coordorigin="0, 0"
wrapcoords=null
/>
background
Element This element describes the fill of the background of a page using vector graphics fills. This illustrates how the rendering description of VML can be extended to existing and new HTML objects.
<!element background (fill) >
<!attlist background
id id #implied --
document-wide unique id --
fill cdata #implied -- Boolean whether to fill the
shape or not --
fillcolor cdata #implied - RGB color to use for the fill --
>
See <shape>
for the descriptions of id
, fill
and fillcolor
.
<background
id=null
fill="true"
fillcolor="white"
/>
The following sub-elements may be used to describe more advanced properties of shapes.
For example, the shape element only allows the description of a solid color fill. One
would use the fill
sub-element to describe a gradient fill.
path
Element This sub-element may appear inside a shape
or a shapetype
to
define the path that makes up the shape. This is done through a string that contains a
rich set of pen movement commands. This sub-element also describes the limo-stretch
point, inscribed textbox rectangle locations, and connection site locations. The
limo-stretch definition and the formulas
element (described below) allow
greater designer control of how the path scales. They allow, for example,
definition of a true rounded corner rectangle where the corners remain circular even
though the rectangle is scaled anisotropically.
<!element path (null)>
<!attlist path
id id
#implied -- document-wide unique id --
v
cdata #implied -- string containing pen movement commands --
limo cdata
#implied -- point to do a limo stretch --
fillok cdata #implied -- path
may be filled --
strokeok cdata #implied -- path may be
stroked --
shadowok cdata #implied -- path may be
used to create a shadow --
arrowok cdata #implied --
arrowheads may be drawn on path --
gradientshapeok cdata #implied -- how to interpret gradientradial --
textpathok cdata #implied -- path is designed for use
with textpath --
textboxrect cdata #implied -- rectangle to hold label text
--
>
stroke
element should be ignored.
fill
element type="gradientradial"
attribute setting.
textpath
element. If not set the textpath
element must be ignored.
Normally textpath paths are not useful unless they are associated with a textpath
element.
@number
where number
is the
formulas ordinal number. The default is the same as the containing block.
The v
attribute string (or the path
property of shape
)
is made up of a rich set of commands as summarized in the following table:
m
moveto
2
Start a new sub-path at the given (x,y) coordinate
l
lineto
2*
Draw a line from the current point to the given (x,y) coordinate which becomes the new
current point. A number of coordinate pairs may be specified to form a polyline.
c
curveto
6*
Draw a cubic b騷ier curve from the current point to the coordinate given by the final
two parameters, the control points given by the first four parameters. The current point
becomes the end point of the b騷ier.
x
close
0
Close the current sub-path by drawing a straight line from the current point to the
original moveto point.
e
end
0
End the current set of sub-paths. A given set of sub-paths (as delimited by end) is
filled using eofill. Subsequent sets of sub-paths are filled independently and
superimposed on existing ones.
t
rmoveto
2*
Start a new sub-path at the coordinate (cpx+x, cpy+y).
r
rlineto
2*
Draw a line from the current point to the given relative coordinate (cpx+x, cpy+y).
v
rcurveto
6*
Cubic b騷ier curve using the given coordinate relative to the current point.
nf
nofill
0
The current set of sub-paths (delimited by end - e
) will not be filled.
ns
nostroke
0
The current set of sub-paths (delimited by end - e
) will not be filled.
ae
angleellipseto
6*
center (x,y) size(w,h) start-angle, end-angle. Draw a segment of an ellipse as
describes using these parameters. A straight line is drawn from the current point to the
start point of the segment.
al
angleellipse
6*
Same as angleellipseto except that there is an implied moveto the starting point of
the segment.
at
arcto
8*
left, top, right, bottom start(x,y) end(x,y). The first four values define the
bounding box of an ellipse. The last four define two radial vectors. A segment of the
ellipse is drawn which starts at the angle defined by the start radius vector and ends at
the angle defined by the end vector. A straight line is drawn from the current point to
the start of the arc. The arc is always drawn in a counterclockwise direction.
ar
arc
8*
left, top, right, bottom start(x,y) end(x,y). Same as arcto however a new sub-path is
started by an implied moveto the start point of the arc.
wa
clockwisearcto
8*
left, top, right, bottom start(x,y) end(x,y). Same as arcto but the arc is drawn in a
clockwise direction.
wr
clockwisearc
8*
left, top, right, bottom start(x,y) end(x,y). Same as arc but the arc is drawn in a
clockwise direction
qx
ellipticalqaudrantx
2*
end(x,y). A quarter ellipse is drawn from the current point to the given end point. The elliptical segment is initially tangential to a line parallel to the x-axis. (i.e. the segment starts out horizontal)
qy
ellipticalquadranty
2*
end(x,y). Same as ellipticalquadrantx except that the elliptical segment is initially tangential to a line parallel to the y-axis. (i.e. the segment starts out vertical)
qb
quadraticbezier
2+2*
(controlpoint(x,y))*, end(x,y) Defines one or more quadratic b騷ier curves by means of control points and an end point. Intermediate (on-curve) points are obtained by interpolation between successive control points as in the OpenType font specification. The sub-path need not be started in which case the sub-path will be closed. In this case the last point of the sub-path defines the start point of the quadratic b騷ier.
VML does not mandate a user interface for editing applications. It attempts to convey
information about the object which is being edited - this may imply the behavior of an
editor. One common operation implied by VML is the need to edit the points in a
path. The edit behavior extensions attempt to identify some common behavior of v
objects so that applications behave consistently however the information encoded is very
low level. Consequently these extensions may be ignored completely by a conforming
application and any conforming application is free to remove or rewrite the edit
information in the path.
The extensions define the behavior of all following points under editing operations which move the points or the associated line segments. Nine different behaviors are identified for the vertices in the path attribute (the end points, not the control points) depending on whether the associated line segment is a line or curve.
ha
AutoLine
0
auto
line
hb
AutoCurve
0
auto
curve
hc
CornerLine
0
corner
line
hd
CornerCurve
0
corner
curve
he
SmoothLine
0
smooth
line
hf
SmoothCurve
0
smooth
curve
hg
SymmetricLine
0
symmetric
line
hh
SymmetricCurve
0
symmetric
curve
hi
Freeform
0
auto
any
The line segment type defines whether the behavior applies to points which are adjacent to lines or whether it applies to points adjacent to curves. The vertex behavior specifies how the two line segments either side of a point are expected to behave as the point is moved.
The auto behavior implements some application-defined algorithm to guess the correct control points when a point is moved. This is, effectively, the default - it implies that the application should use other information to determine the control point behavior. The symmetric, smooth and corner behaviors determine how one control point behaves when the other at that vertex is moved. The freeform behavior does not recalculate control point position as vertices are moved.
v
attribute valueThis value consists of commands followed by zero or more parameters. The number of parameters is given in the table above. In this table, the suffix "*" indicates that the parameter set may be repeated (but the number of parameters must be a multiple of the given number). The quadratic b騷ier must have more than two pairs of parameters.
m 0,0
" and "m0 0
" are both acceptable.c 10,10,0,0,25,13
" and "c 10,10,,,25,13
"
are equivalent.formula
element with a list of formulas that may be substituted into the path using the @
symbol followed by the number of the formula. The adj
property of the shape
contains the input parameters for these formulas. E.g. "moveto @1@4
".
The evaluations of the formulas are substituted into the appropriate positions.
Note that @
also serves as a delimiter.In the event that a path is malformed VML requires the following behavior if the page is displayed.
An application is also permitted to fail to display the page (with a diagnostic) or to alert the user that some content is malformed.
<path
id=null
v=null
limo="0,0"
textboxrect=null
/>
formulas
Element This sub-element may appear inside a shape
or a shapetype
to
define formulas that can vary the path of a shape, its inscribed text rectangles, and
connection sites. Formula values change as the adj
values change on the
shape. Formulas can reference other formulas defined earlier in the same formulas
element.
<!element formulas (f)*>
<formulas>
none
f
element of formulas
Each f
element defines a single value as the result of the evaluation of
an expression. The expression is defined by the cdata
content of the eqn
attribute and has the general form of an operation followed by up to three arguments,
which may be adjust handle values, the results of earlier guide formulas, fixed numbers or
pre-defined values.
<!element f (null)>
<!attlist f
eqn cdata #implied-- string with the formula definition --
>
A single formula, evaluated as described below.
In the following table, the arguments are given the names v
,
P1
, P2
(in that order), thus
the element is simply:
<f eqn="operation v P1 P2">
mod
3
no
The square root of ( v squared plus P1 squared plus P2 squared )
Modulus (etc.)
sumangle
3
yes
v + P1ラ216 - P2ラ216
v
is an existing angle (scaled by 216),P1
and P2
are numbers of
degrees.
The formulas are evaluated to full precision - however the result is always a 32-bit integer. Formula authors should avoid formulas which are discontinuous - not only are many of the trigonometric operations inexact, the transformations within the coordinate spaces are also inexact. This can mean that a set of formulas which is discontinuous evaluates to give very different path values with the same input on two different systems.
When an operation is marked as exact then a conforming implementation must always
generate the correct arithmetic answer (unless the calculations overflow internally).
The product
operation is required to round to the nearest integer.
If the result is exactly 0.5 then it must be rounded up to the next
numerically greater integer. (So the absolute value of a negative result will
decrease - -1.5 must be evaluated as -1.)
The mid
operation is required to round towards 0.
All other operations are inexact, however the implementation must round non-integral values down (towards -infinity) and should perform internal calculations with this form of rounding.
The arguments used in the evaluation of a formula are normally either fixed numbers,
the result of the evaluation of a previous guide formula or an adjust value - the
value of the corresponding entry in the shape adj
attribute. Fixed
numbers must be positive integral values in the range 0 to 65535, i.e. unsigned 16 bit
numbers.
@ n
The value of guide formula n. n must be less than the current
guide formula index (0 is the first guide formula index.)
# n
Adjust (adj
) value n. n must be in the range 0 to 7.
width
The width defined by the coordsize
attribute.
height
The height defined by the coordsize
attribute.
xlimo
The x value of the limo
attribute.
ylimo
The y value of the limo
attribute.
hasstroke
1 if the shape has a stroke operation, 0 if it does not. (The on
attribute of the stroke
element, expressed as a number.)
hasfill
1 if the shape has a fill operation, 0 if it does not. (The on
attribute of the fill
element, expressed as a number.)
pixellinewidth
The line width in output device pixels. This is used to outset lines from the edge of
a rectangle on the assumption that the implementation draws to lower right pixel in
preference to the upper left pixel when a line is on a pixel boundary.
pixelwidth
The width of the shape in device pixels (i.e. the coordsize
width
transformed into device space.)
pixelheight
The height of the coordsize
in device pixels.
emuwidth
The width of the coordsize
in EMUs.
emuheight
The height of the coordsize
in EMUs.
emuwidth2
Half the width of the coordsize
in EMUs.
emuheight2
Half the height of the coordsize
in EMUs.
Notice that a pixel
value should be in a square coordinate space - so it
may be necessary to (effectively) report a higher device resolution than that which is
available if the device has non-square pixels. The pixel value parameters serve the
specific purpose of allowing a formula author to handle some aspects of device
pixelization. They must not be used to produce paths with elements which have a
constant physical size. The EMU parameters must be used for this purpose.
VML limits the total number of adjust values, guide formulas and adjust handles.
<formulas>
<f eqn="sum #0 0 10800"/>
<f eqn="prod #0 2 1"/>
<f eqn="sum 21600 0 @1"/>
<f eqn="sum 0 0 @2"/>
<f eqn="sum 21600 0 @3"/>
<f eqn="if @0 @3 0"/>
<f eqn="if @0 21600 @1"/>
<f eqn="if @0 0 @2"/>
<f eqn="if @0 @4 21600"/>
<f eqn="mid @5 @6"/>
<f eqn="mid @8 @5"/>
<f eqn="mid @7 @8"/>
<f eqn="mid @6 @7"/>
<f eqn="sum @6 0 @5"/>
</formulas>
handles
Element This sub-element may appear inside a shape
or a shapetype
to
define user interface elements which can vary the adj
values on the shape
,
thereby changing the value of formulas
and the rendering of a path based on formulas
and adj
values.
<!element handles (h)* >
none.
h
sub-element of handles
Each handle is specified using a single h
sub-element. This defines
which pair of adjust values store the position of the handle and how the handle position
can vary as the handle is adjusted. The handle is moved under user control, within
the constraints imposed by the handle definition, and the final position is stored back in
the adjust values.
Positions are stored within the shape
coordinate space - this means that
handle positions are independent of the actual size of the shape.
<!element h (null) >
<!attlist h
position cdata #implied -- position of the handle --
polar cdata #implied -- center for a polar
(circular) handle --
map cdata #implied -- range to map the
handle value to --
invx cdata #implied -- invert position in X --
invy cdata #implied -- invert position in
Y --
switch cdata #implied -- switch x/y according to shape
aspect ratio --
xrange cdata #implied -- limits x range of handle --
yrange cdata #implied -- limits y range of handle --
radiusrange cdata #implied -- limits radius of polar handle --
>
@2
), center
, topleft
, bottomright
,
or an adjust value (e.g. #3
). If a constant, formula value, center
,
topleft
, or bottomright
is specified, the handle position is
fixed in that dimension. If an adjust value (e.g. #3
) is specified, the
handle is free to move that dimension and the adjust value is determined by the position
of the handle.If the polar
attribute is specified, than the position
attribute represents the radius and angle values of the handle instead of x and y.
coordsize
range into the given range.
coordoriginx
+ coordsizex - x
.
coordoriginy
+ coordsizey - y
.
@2
).
If a value is omitted, the handle is free to move without limit in that direction.
@2
). If a
value is omitted, the handle is free to move without limit in that direction.
@2
). If a value is
omitted, the handle is free to move without limit in that direction. This applies
only to polar adjust handles.
<handles>
<h
position=null
polar=null
map="0, 1000"
invx="false"
invy="false"
switch="false"
xrange="0, 1000"
yrange="0, 1000"
radiusrange="0, 1000"
/h>
</handles>
fill
Element This sub-element may appear inside a shape
, shapetype
, background
or most predefined shape elements to describe how the path should be filled if something
beyond a solid color fill is desired. The attributes of the fill
element can used to describe a powerful set of image or gradient based fill patterns.
Extensions to the VML fill definition may be encoded as sub-elements of fill
.
<!element fill any>
<!attlist fill
id id
#implied -- document-wide unique id --
type cdata #implied
on cdata #implied
color cdata #implied
color2 cdata #implied
opacity cdata #implied
src cdata #implied
size cdata #implied
origin cdata #implied
position cdata #implied
alignshape cdata #implied
colors cdata #implied
angle cdata #implied
focus cdata #implied
focussize cdata #implied
focusposition cdata #implied
method cdata #implied
>
fill
attribute in shape
.
This overrides the <shape> fill attribute.
fillcolor
attribute in shape
.
This overrides the shape
fillcolor
attribute.
fillcolor
attribute in shape
) is 0% and secondary color (color2
attribute)
is 100%.
<fill
id=null
type="solid"
on="true"
color="white"
opacity="1.0"
color2="white"
opacity2="1.0"
src=null
size="auto"
origin="center"
position="center"
aspect="ignore"
alignshape="true"
colors=null
angle="0"
focus="0"
focussize="0,0"
focusposition="0,0"
method="sigma"
/>
stroke
Element The sub-element may appear inside a shape
, shapetype
or any
predefined shape element to describe how to draw the path if something beyond a solid line
with a solid color is desired. The attributes of the stroke
element can
used to describe a powerful set of stroke properties. Extensions to the VML stroke
definition may be encoded as sub-elements of the stroke
element.
<!element stroke any>
<!attlist stroke
id
id
#implied -- document-wide unique id --
on
cdata
#implied
weight cdata #implied
color cdata
#implied
color2 cdata #implied
opacity cdata #implied
style cdata
#implied
miterlimit cdata #implied
joinstyle cdata #implied
endcap cdata #implied
dashstyle cdata #implied
filltype cdata #implied
src
cdata #implied
imagesize cdata #implied
imagealignshape cdata #implied
startarrow cdata #implied
startarrowwidth cdata #implied
startarrowlength cdata #implied
endarrow cdata #implied
endarrowwidth cdata #implied
endarrowlength cdata #implied
>
The dashstyle
attribute allows the user to specify a custom defined dash
pattern. This is done using a series of numbers. Dash styles are defined in
terms of the length of the dash (the drawn part of the stroke) and the length of the space
between the dashes. The lengths are relative to the line width - a length of
"1" is equal to the line width. The endcap
style is applied
to each dash, the arrow style is not. The string first defines the length of the
dash then the length of the space. This may be repeated to form complex dash styles.
The string should always contain a pair of numbers. If it contains an odd
number of numbers the last should be disregarded. The following table lists some
typical values and a description of the intended effect. "0" implies a dot
which should be four-fold symmetrical (with round end caps it should be a circle).
If the line end cap is flat
a viewer should choose a built-in operating
system dash where possible (i.e. something which is fast to draw).
<stroke id=null
on="true"
weight="1pt"
color="white
opacity="1.0"
linestyle="single"
miterlimit="8.0"
joinstyle="round"
endcap="round"
dashstyle="solid"
filltype="solid"
color2="white"
src=null
imagesize="auto"
imagealignshape="true"
startarrow="none"
startarrowwidth="medium"
startarrowlength="medium"
endarrow="none"
endarrowwidth="medium"
endarrowlength="medium"
/>
shadow
Element This sub-element may appear inside a shape
or a shapetype
to
define a shadow effect on a shape.
<!element shadow (null) >
<!attlist shadow
id id #implied --
document-wide unique id --
on cdata #implied
type cdata #implied
obscured cdata #implied
color cdata #implied
opacity cdata #implied
offset cdata #implied
color2 cdata #implied
offset2 cdata #implied
origin cdata #implied
matrix cdata #implied
>
RGB(128,128,128) The color of the primary shadow.
<shadow
id=null
on="false"
type="single"
obscured="false"
color="rgb(128,128,128)"
opacity="1.0"
offset="2pt,2pt"
color2="rgb(203,203,203)"
opacity2="1.0"
offset2="0pt,0pt"
origin="0,0"
matrix=null
</shadow>
textbox
Element This sub-element may appear inside a shape
or a shapetype
to
define text that is to appear inside the shape. This text may contain rich formatting and
will be rendered to fit inside the textboxrect
defined by the path
element.
<!element textbox (null)>
<!attlist textbox
id id #implied -- document-wide unique id
--
style cdata #implied -- style info for the HTML text --
>
<textbox
id=null
style='
v-padding-auto: true;
padding-left: 0.1in;
padding-top: 0.05in;
padding-right: 0.1in;
padding-bottom: 0.05in;
v-text-anchor: top;
v-text-wrapping: true;
v-text-flow: horizontal;
v-text-direction: rtl'
/>
textpath
Element This sub-element may appear inside a shape
or a shapetype
to
define a vector path based on the text data, font and font styles supplied. The path
which results is then mapped into the region defined by the v
attribute of
the shape.
<!element textpath (null) >
<!attlist textpath
id id #implied --
document-wide unique id --
style cdata #implied -- style info for the HTML text --
on cdata #implied -- whether or not to use the
textpath --
fitshape cdata #implied
fitpath cdata #implied
trim cdata #implied
xscale cdata #implied
string cdata #implied
>
<textpath
on=false
style='
font:
null;
font-family:
null;
font-style:
normal;
font-weight:
normal;
font-size:
normal;
font-variant:
normal;
text-decoration: normal;
v-text-shadow: false;
text-align:
center;
v-text-align-alt: stretch-justify;
v-letter-tightening: 0;
v-letter-tracking: 0;
v-text-kern:
false;
v-rotate-letters: false;
v-same-letter-heights: false'
fitshape="false"
fitpath="false"
trim="false"
xscale="false"
text=null
/>
imagedata
Element This sub-element may appear inside a shape
or a shapetype
to
define a picture to be rendered on top of a shape. There is also a top-level element, image
,
which has these attributes, along with most of the same attributes as shape
.
<!element imagedata (null)>
<!attlist imagedata
id id #implied --
document-wide unique id --
src cdata #implied
cropleft cdata #implied
croptop cdata #implied
cropright cdata #implied
cropbottom cdata #implied
gain cdata #implied
blacklevel cdata #implied
gamma cdata #implied
chromakey cdata #implied
grayscale cdata #implied
bilevel cdata #implied
>
The chromakey may specify a pixel index using the extended notation for colors.
The chromakey is applied before any image transformation - including color modifications, gamma correction and scaling.
unsigned
Y709FromRGB(unsigned ur, unsigned ug, unsigned ub)
{
return 3579139 * ur + // 0.2125
12049489 * ug + // 0.7154
1214381 * ub; // 0.0721
}
(This is a 32 bit value - shift left 24 to get an 8 bit gray level value.)
inline
ULONG UBlackWhite(ULONG uc)
{
if (uc < 128) return 0;
return 255;
}
To convert an image to black and white grayscale
is also specified.
The gray level operation happens first. Because the precise luma calculation
is specifed the bi-level operation will behave in the same way on all systems.
<imagedata
id=null
src=null
href=null
linktype="copy"
cropleft="0"
croptop="0"
cropright="0"
cropbottom="0"
embosscolor="none"
gain="1"
blacklevel="0"
gamma="1"
chromakey="none"
grayscale="false"
bilevel="false"
/>
Predefined shapes serve two purposes - they provide a more compact representation of a small number of very frequently encountered drawing operations (particularly rectangles and circles) and they give an easy to use form for people who hand-edit VML.
Predefined shapes have the same properties as shape
except that the type
attribute is not permitted. In some cases the definition of the shape precludes use
of some of the standard shape properties. These exceptions are given below.
line
Element This element is used to specify a straight line.
<!element line (%shape.elements;)* >
<!attlist line %coreattrs; %shapeattrs;
from cdata #implied
to cdata #implied
>
shape
are ignored
in a line
.
<line
from="0 0"
to="10 10"
id=null
href=null
target=null
class=null
title=null
alt=null
style='visibility: visible'
opacity="1.0"
chromakey="null"
stroke="true"
strokecolor="black"
strokeweight="1"
fill="true"
fillcolor="white"
print="true"
coordsize="1000,1000"
coordorigin="0 0"
/>
polyline
Element The polyline element is used to define shapes made up of connected line segments.
<!element polyline (%shape.elements;)*>
<!attlist polyline %coreattrs; %shapeattrs;
points cdata #implied
>
shape
are ignored
in a polyline
.
It is necessary to compute the bounding rectangle of the polyline to determine the content width and height.
<polyline
points="0 0 10 10 20 0"
id=null
href=null
target=null
class=null
title=null
alt=null
style='visibility: visible'
opacity="1.0"
chromakey="null"
stroke="true"
strokecolor="black"
strokeweight="1"
fill="true"
fillcolor="white"
print="true"
coordsize="1000,1000"
coordorigin="0 0"
/>
curve
Element This element is used to draw a cubic b騷ier curve.
<!element curve (%shape.elements;)*>
<!attlist curve %coreattrs; %shapeattrs;
from cdata #implied
control1 cdata #implied
control2 cdata #implied
to cdata #implied
>
shape
are ignored
in a line
.
<curve
from="0 0"
control1="10 10"
control2="20 0"
to="10 10"
id=null
href=null
target=null
class=null
title=null
alt=null
style='visibility: visible'
opacity="1.0"
chromakey="null"
stroke="true"
strokecolor="black"
strokeweight="1"
fill="true"
fillcolor="white"
print="true"
coordsize="1000,1000"
coordorigin="0 0"
/>
rect
ElementThis element is used to draw a simple rectangle. The rectangle is defined by the content width specified in the CSS2 properties.
<!element rect (%shape.elements;)*>
<!attlist rect %coreattrs; %shapeattrs;>
<rect
id=null
href=null
target=null
class=null
title=null
alt=null
style='visibility: visible'
opacity="1.0"
chromakey="null"
stroke="true"
strokecolor="black"
strokeweight="1"
fill="true"
fillcolor="white"
print="true"
coordsize="1000,1000"
coordorigin="0 0"
/>
roundrect
Element This element is used to draw a rectangle with rounded corners.
<!element roundrect (%shape.elements;)*>
<!attlist roundrect %coreattrs; %shapeattrs;
arcsize cdata #implied -- size of arc on corners of rectangle --
>
<roundrect
arcsize="0.2"
id=null
href=null
target=null
class=null
title=null
alt=null
style='visibility: visible'
opacity="1.0"
chromakey="null"
stroke="true"
strokecolor="black"
strokeweight="0.75pt"
fill="true"
fillcolor="white"
print="true"
coordsize="1000,1000"
coordorigin="0 0"
/>
oval
Element This element is used to draw an oval defined by the CSS2 content width and height.
<!element oval (%shape.elements;)*>
<!attlist oval %coreattrs; %shapeattrs;>
<oval
position="0 0"
size="100 100"
id=null
href=null
target=null
class=null
title=null
alt=null
style='visibility: visible'
opacity="1.0"
chromakey="null"
stroke="true"
strokecolor="black"
strokeweight="0.75pt"
fill="true"
fillcolor="white"
print="true"
coordsize="1000,1000"
coordorigin="0 0"
/>
arc
Element This element is used to draw an arc defined as a segment of an oval. The content width and height define the width and height of that oval. The arc is defined by the intersection of the oval with the start and end radius vectors given by the angles. The angles are calculated on the basis of a circle (width equal to height) which is then scaled anisotropically to the desired width and height.
<!element arc (%shape.elements;)*>
<!attlist arc %coreattrs; %shapeattrs;
startangle cdata #implied
endangle cdata #implied
>
<arc
startangle="0"
endangle="90"
id=null
href=null
target=null
class=null
title=null
alt=null
style='visibility: visible'
opacity="1.0"
chromakey="null"
stroke="true"
strokecolor="black"
strokeweight="0.75pt"
fill="true"
fillcolor="white"
print="true"
coordsize="1000,1000"
coordorigin="0 0"
/>
image
ElementThis element is used to draw a bitmap that has been loaded from an external source.
There is an implied rectangle that is the same size as the image. Any stroke or fill will
be applied to this implied rectangle. The fill will be behind the image and it will
therefore only be visible through transparent areas of the bitmap. The stroke is
drawn on top of the image. The bitmap may have transparency encoded in the file (if
it is a PNG bitmap) or a chromakey color value may be specified using the chromakey
attribute.
<!element image (%shape.elements;)*>
<!attlist image %coreattrs; %shapeattrs;
src cdata #implied
cropleft cdata #implied
croptop cdata #implied
cropright cdata #implied
cropbottom cdata #implied
embosscolor cdata #implied
gain cdata #implied
blacklevel cdata #implied
gamma cdata #implied
grayscale cdata #implied
bilevel cdata #implied
>
<image
src=null
cropleft="0"
croptop="0"
cropright="0"
cropbottom="0"
embosscolor="none"
gain="1.0"
blacklevel="0"
gamma="0"
chromakey="none"
grayscale="false"
bilevel="false"
id=null
href=null
target=null
class=null
title=null
alt=null
style='visibility: visible'
opacity="1.0"
chromakey="null"
stroke="true"
strokecolor="black"
strokeweight="1"
fill="true"
fillcolor="white"
print="true"
coordsize="1000,1000"
coordorigin="0 0"
/>
VML is based on several other standard forms. Some of these are as yet incomplete (CSS2, XML namespaces). This section references those documents which are normative so far as VML is concerned - they define behavior which must be both understood and implemented for VML to function correctly.
VML does not rely on the definition of PostScript, however that definition is extremely helpful in understanding VML.
The original W3C requirements specification can be found at W3C Scalable Graphics Requirements.
VML is based on well-established vector graphical techniques. The intention is to make the references in this section reflect parts of that work which are particularly important to VML.