W3C NOTE-drawml-19981203

DrawML Specification

W3C Note, 03-Dec-1998

This Version:
http://www.w3.org/TR/1998/NOTE-drawml-19981203
Latest Version:
http://www.w3.org/TR/NOTE-drawml
Author:
Håkan Lothigius <lhl@excosoft.se>, Excosoft AB

Status of this document

This document has been submitted to the World Wide Web Consortium (see Submission Request, W3C staff comment). The submission includes a DTD and two Java class definitions: DrawMLShape and DrawMLPainter.

This document is a NOTE made available by W3C for discussion only. This indicates no endorsement of its content, nor that W3C has, is, or will be allocating any resources to the issues addressed by the NOTE.

Abstract

This document is the DrawML specification. DrawML is an application of Extensible Markup Language (XML) 1.0.

DrawML is a 2D scalable graphics language designed to facilitate the creation of simple technical drawings. Furthermore (and most importantly), DrawML focuses on the process of maintaining and refining a drawing. A drawing should be as easy to update as the document it resides in.

DrawML is based on the following requirements and criteria:

The reason for the focus on maintenance is the increased importance of intranets. Up to now internet technology has been used primarily for publishing. People working within an intranet expect to create and change documents on-the-fly.

DrawML is a very simple language. It only defines five elements.

The Concept

Embedding

A DrawML drawing is embedded in the SGML/XML document. If required parent DTD elements can be embedded in the DrawML drawing. Compare to a CALS table, where the content model for a cell is declared in the main DTD. In DrawML it is possible to insert paragraphs, lists, images, tables, etc. inside a drawing.

There are several advantages accruing from a tight integration of the document and the drawings it contains.

The drawml element introduces a drawing in a document. At this point the "rendering engine" enters the DrawML mode in which the elements inside the drawing are drawn in accordance with the rules set forth in this specification. Somewhere in the drawing we want to include other non drawing elements. The lmward element (drawml spelled backwards!) temporarily leaves the DrawML mode and enters the ordinary rendering mode.

In the following example a paragraph with an emphasized word is written inside a rectangular shape.

<drawml>
 <shape type="rectangle">
  <lmward>
   <p>This is <em>my</em> text</p>
  </lmward>
 </shape>
</drawml>
Expansion can be to the left

Automatic Sizing

We expect a table cell to adjust to its content and a paragraph to adjust to the frame width and we should expect similar functionality in a drawing.

One of the important concepts underlying DrawML is that shapes adjust to their content by default (just like cells in a table). A DrawML shape may contain other shapes.

For instance a shape will expand if the text placed inside it does not fit.

<drawml>
 <shape type="rectangle"></shape>
 <shape type="rectangle" width="100">
  <lmward>
   <p>This is <em>my</em> text</p>
  </lmward>
 </shape>
</drawml>
Shapes expand downwards

In the above case the width of the rectangle was explicitly set, which forced the text in the paragraph to wrap.

Automatic Positions

By placing shapes inside other shapes it is possible to arrange and group intelligently. The parent shape can be invisible and thus be used for the sole purpose of grouping. By default, shapes are arranged horizontally.

<drawml>
 <shape type="rectangle">
  <shape type="rectangle">
   <lmward>Hello</lmward>
  </shape>
  <shape type="rectangle">
   <lmward>World</lmward>
  </shape>
 </shape>
</drawml>
Two rectangles with text inside another rectangle

DrawML drawings work with structures rather than coordinate positions. When the user adds a new shape in the structure the application will make room for the new shape automatically.

<drawml>
 <shape type="rectangle">
  <shape type="rectangle">
   <lmward>Hello</lmward>
  </shape>
  <shape type="rectangle">
   <lmward>new</lmward>
  </shape>
  <shape type="rectangle">
   <lmward>World</lmward>
  </shape>
 </shape>
</drawml>
A new rectangle added

Shapes can also be arranged vertically.

<drawml>
 <shape type="rectangle" arrange="vertical">
  <shape type="rectangle">
   <lmward>Hello</lmward>
  </shape>
  <shape type="oval"></shape>
  <shape type="oval"></shape>
  <shape type="rectangle">
   <lmward>World</lmward>
  </shape>
 </shape>
</drawml>
Build direction is downwards

A position can be explicitly defined using a coordinate. This coordinate is relative to its parent shape so when a parent is moved, its child is moved with it. Each shape defines a coordinate system for its children.

<drawml>
 <shape type="rectangle">
  <shape type="oval" x="100" y="20">
  </shape>
 </shape>
</drawml>
Build direction is downwards

Automatic Connections

Drawing objects are often connected, e.g., an arrow points from one object to another, a group of objects are connected to a parent object in a hierarchical structure, etc. If objects are moved connections should adjust to the new layout. This effect is often referred to as the "rubber band" effect.

In DrawML shapes may have one or more hook positions. These positions are suitable connection points. Connections are defined with the line element. A connection consists of two or more positions (pos elements). Each position is either glued to a hook position in a shape or explicitly assigned a coordinate position.

A rectangle, for example, typically has four hook positions; W, N, E and S (west, north, east and south).

<drawml>
 <shape type="rectangle" shape-id="d1">
  <lmward>Hello</lmward>
 </shape>
 <shape type="rectangle" x="50" y="50" shape-id="d2">
  <lmward>World</lmward>
 </shape>
 <line>
  <pos attach-to="d1" attach-point="S"/>
  <pos attach-to="d2" attach-point="N"/>
 </line>
</drawml>
Connector between rectangles

Sometimes we may want to connect to the nearest point on a shape. This point is defined with the reserved hook name $nearest.

<drawml>
 <shape type="oval" shape-id="d1">
  <lmward>Hello</lmward>
 </shape>
 <shape type="oval" x="50" y="50" shape-id="d2">
  <lmward>World</lmward>
 </shape>
 <line>
  <pos attach-to="d1" attach-point="$nearest"/>
  <pos attach-to="d2" attach-point="$nearest"/>
 </line>
</drawml>
Connector between ovals

A line may connect several shapes. The line is by default drawn from shape to shape in the order of the positions.

Serial connection

On the other hand, a line can connect the involved shapes in three other ways: horizontally, vertically or centrally. The "centre of gravity" gives the renderer a default "central position" to be used as visualized below.

Horizontal connection Vertical connection Spider connection

The "central position" can be specified explicitly.

Horizontal connection, explicit point Horizontal connection, explicit point Horizontal connection, explicit point

Shapes in Java

The success of a standard often depends on its extendability. In DrawML all shapes are defined using Java, including rectangles and circles. The power of a programming language such as Java gives shape developers the necessary flexibility.

The following example is a house shape.

<drawml>
 <shape type="house">
 </shape>
</drawml>
House shape

When child shapes are positioned inside the shape the house should be bigger. It is the shape that decides how the house should adapt to its children. Note that the roof is not getting any higher, ,just wider.

<drawml>
 <shape type="house">
    <lmward>A house</lmward>
 </shape>
</drawml>
House shape with  children

The Java shapes have a CalcSize() method that calculates each size. The renderer calls these routines when calculating the individual positions. The interesting point is that each shape asks the renderer for the size of the shape's children.

House shape with  children
public void CalcSize()
{
   SetW( 7 + 5 + GetWChild() + 5 + 7 );   // Set shape width
   SetH( 10 + 5 + GetHChild() + 5 );      // Set shape height
}

After calculating positions the renderer then calls the DrawShape() routine for each shape. The Java class uses a PAINTER class to do the actual drawing.

The Java-code to draw the house is as follows:

public void DrawShape()
{
   Painter.NewPath();                          // Clear painter
   Painter.MoveTo( 0, 10 );
   Painter.LineTo( MyW()/2, 0 );
   Painter.LineTo( MyW(), 10 );
   Painter.ClosePath();
   Painter.Stroke();                           // Draw roof
   Painter.NewPath();
   Painter.MoveTo( 7, 10 );
   Painter.LineTo( MyW() - 7, 10 );
   Painter.LineTo( MyW() - 7, MyH() );
   Painter.LineTo( 7, MyH() );
   Painter.ClosePath();
   Painter.Stroke();                           // Draw front
}

An Example

The following example demonstrates several DrawML features.

<drawml>
 <shape arrange="vertical" visibility="invisible" shape-id="i1">
  <shape shape-id="d1">
   <lmward>
    <title>System X</title>
   </lmward>
  </shape>
  <shape visibility="invisible" shape-id="i2">
   <shape shape-id="d1">
    <lmward>
     <subtitle>Subsystem A</subtitle>
     <para>This is text in a para.</para>
    </lmward>
   </shape>
   <shape shape-id="d2">
    <lmward>
     <subtitle>Subsystem B</subtitle>
     <list>
      <list-item>This is a list.</list-item>
      <list-item>This is the second item.</list-item>
     </list>
    </lmward>
   </shape>
  </shape>
  <line connect="horizontal">
   <pos attach-to="d1"/>
   <pos attach-to="i2.d1" arrowed="yes"/>
   <pos attach-to="i2.d2" arrowed="yes"/>
  </line>
 </shape>
</drawml>
A System rectangle and two Sub-system rectangles below

The drawing consists of two invisible objects that have the sole purpose of grouping other objects, horizontally and vertically. Elements from the parent DTD (title, subtitle, para, list and list-item) are used inside the rectangles. Connections are glued to objects.

The drawing is easy to maintain and refine. If a new box is added or if more text is added in any rectangle, an application will still be capable of formatting the drawing appropriately.

Appendix

Elements and Attributes

Element drawml

A drawml element defines a drawing area. It has a default size and is invisible.

Content Model
(shape|line|lmward)*
Attributes
Name Value(s) Default Value
width points (automatic)
height points (automatic)
min-width points 50
min-width points 50
WIDTH, HEIGHT

The WIDTH and HEIGHT attributes specify an explicit drawing size. By default a drawing adjusts to its content.

MIN-WIDTH, MIN-HEIGHT

The MIN-WIDTH and MIN-HEIGHT attributes define the extent to which a drawing is allowed to shrink.

Element shape

The shape element is a generic element. The characteristics of the shape is defined in a separate Java class. The shape can be anything from a simple rectangle to a complicated figure.

Content Model
(shape|line|lmward)*
Attributes
Category Name Value(s) Default Value
Main type shape name "rectangle"
shape-id shape id
visibility "visible", "invisible", "dimmed" "visible"
Position x points (automatic)
y points (automatic)
z points 0
delta-x points 0
delta-y points 0
Size width points (automatic)
height points (automatic)
min-width points 50
min-height points 50
max-width points (none)
max-height points (none)
perfect "yes", "no" "no"
Line line-width points 1
line-color color "black"
Fill filled "yes", "no" "yes"
fill-color color "white"
Shadow shadowed "yes", "no" "no"
shadow-color color "gray"
shadow-x points 5
shadow-y points 5
Children arrange "horizontal", "vertical" "horizontal"
child-separation points 5
child-halign "left", "center", "right" "center"
child-valign "top", "center", "bottom" "center"
child-wpad points 5
child-hpad points 5
type

The type attribute defines the shape type.

<shape type="house">
  ...
</shape>

The DrawML engine searches for a Java class with the specified type name (in this case house.class).

shape-id

The shape-id attribute assigns an id to the shape. It must be unique among all its sibling.

visibility

The visibility attribute specifies whether a shape is visible, invisible or dimmed.

x, y

The x and y attributes specify the shape position relative its parent. If these attributes are not specified the shape is positioned according to automatic positioning rules.

<shape type="rectangle">
 <shape type="rectangle" x="20" y="40">
 </shape>
</shape>
X and Y relative parent shape
z

The z attribute defines the order in which shapes are drawn inside a shape. Shapes with lesser Z values are overlaid by shapes with greater Z values. If z is not specified or shapes have the same Z value, the shapes are drawn in the order they are specified.

delta-x, delta-y

The delta-x and delta-y attributes define a delta displacement from the current position. The current position is the position specified explicitly with the attributes x and y or implicitly with the automatic positioning algorithm.

<shape type="rectangle">
 <shape type="rectangle" delta-y="40">
 </shape>
</shape>
A delta displacement
width, height

The width and height attributes specify the explicit size of a shape. Automatic resizing will be inhibited.

min-width, min-height, max-width, max-height

The min-width and min-height attributes define the extent to which a shape is allowed to shrink.

The attributes max-width and max-height define the extent to which a shape is allowed to grow.

perfect

The perfect attribute has different meanings for different shapes. The shape designer decides what "perfect" means for his shape. A perfect rectangle will be a square and a perfect oval will be a circle.

A perfect rectangle A perfect oval
line-width

The line-width attribute defines the width of a shape's outline in points. Default line width is 1 point.

line-color

The line-color attribute determines the outline color of a shape. The default value is black.

filled

The filled attribute defines whether the shape is filled or not.

fill-color

The fill-color attribute determines the fill color of a shape. The default value is white.

shadowed

The shadowed attribute defines whether a shape is shadowed or not.

shadow-color

The shadow-color attribute determines the shadow color of a shape.

shadow-x,shadow-y

The shadow-x and shadow-y attributes specifies the offset of the shadow. Negative values are possible. Default offset is 10 points.

arrange

The arrange attribute specifies whether children are positioned horizontally (default) or vertically.

child-separation

The child-separation attribute defines the spacing of positioned child shapes. The default is 5 points.

Two rectangles with a default separation
child-valign, child-halign

The child-valign and child-halign attributes define how child shapes are aligned vertically and horizontally.

<shape type="rectangle" child-valign="top">
 <shape type="rectangle" height="10"></shape>
 <shape type="rectangle" height="30"></shape>
 <shape type="oval"></shape>
</shape>
Allignment at top
<shape type="rectangle" child-valign="bottom">
 <shape type="rectangle" height="10"></shape>
 <shape type="rectangle" height="30"></shape>
 <shape type="oval"></shape>
</shape>
Allignment at bottom
child-wpad, child-hpad

The child_wpad and child-hpad attributes define a padding area around the children.

Element line

A line is a shape built up from positions. It must have at least two positions.

Content Model
(pos, pos+)
Example
<line>
 <pos x="0" y="0"/>
 <pos x="50" y="50"/>
 <pos x="100" y="50"/>
 <pos x="50" y="0"/>
</line>
Line
Attributes
Name Value(s) Default Value
z integer
connect "serial", "vertical", "horizontal", "central" "serial"
grav-x points (centre of gravity)
grav-y points (centre of gravity)
line-width points 1
line-color color "black"
z

The z attribute defines the order in which shapes are drawn inside a shape. Shapes with lesser Z values are overlaid by shapes with greater Z values. If z is not specified or shapes have the same Z value, the shapes are drawn in the order they are specified.

connect

The connect attribute specifies how the included positions should be connected.

grav-x, grav-y

The grav-x and grav-y attributes defines an explicit "centre of gravity" point used when connect type is horizontal, vertical or central.

line-width

The line-width attribute defines the width of the line in points. Default line width is 1 point.

line-color

The line-color attribute determines the color of the line. The default value is black.

Element pos

A pos element is primarily used to define lines. A position can be an explicit coordinate position or hook point on a shape. defined

Content Model
EMPTY
Example
<pos attach-to="d1" attach-point="S" />
<pos attach-to="d1" attach-point="S" delta-x="10" delta-y="-5" />
<pos x="15" y="40" />
Attributes
Name Value(s) Default Value
x points
y points
attach-to shape id
attach-point hook name
delta-x points 0
delta-x points 0
arrowed points "no"
x, y

The x and y attributes define an explicit coordinate for the position.

attach-to, attach-point

The attach-to attribute specifies a shape ID and the attach-point attribute specifies a hook position on that shape.

<pos attach-to="d1" attach-point="S" />

To address a shape inside another shape the id is qualified with the parent shape id. This could be done to any level.

<pos attach-to="town.house1.door" attach-point="S" />
delta-x, delta-y

The delta-x and delta-y attributes define a delta displacement from the current position. The current position is the position specified with the attributes x and y or with the attach attributes.

arrowed

The arrowed attribute specifies if an arrow should be drawn at the position.

Element lmwarD

The lmward element is an element that switches context back to parent DTD elements. It serves as a "container" element for paragraphs, images, tables, lists or whatever element that is allowed inside the drawing.

Content Model
ANY

(The content model could be redefined in the main DTD by means of the lmward-content parameter entity)

Example
<lmward>
 <para>This is a paragraph.</para>
 <warning>And this is a warning!</warning>
</lmward>

Units

The unit for coordinates and dimensions is the point. Examples of valid values:

0
-4
64.75
99999

A color is specified as in the CSS standard, either with a predefined name, e.g. "red" or with an RGB value, e.g. rgb(255,0,0).

The DTD

The DrawML element and attribute definitions are in a separate file and should be included in the DTD in the following manner.

<!ENTITY % drawml SYSTEM "drawml.elm" >
%drawml;

Shape development

DrawML shapes are implemented with Java. When the renderer reads a DrawML drawing it discovers shapes of various types. Each shape type should correspond to a Java class file. The renderer then asks each Java shape to report its size, its hooks and where its first child, if any, should be positioned. When all this information is collected the renderer is able to calculate the coordinate position for each shape. It then calls each shape to draw itself.

A Java shape should extend the DrawMLShape base class. The actual drawing of a shape is accomplished through the DrawMLPainter class.


Chris Lilley, W3C staff contact

Valid HTML 4.0!  Made with CSS