Leonardo's world is a two-dimensional plane. X co-ordinates are positive moving right and Y co-ordinates are positive moving down. Valid co-ordinates in both dimensions are integers in the range -32768 to 32767 inclusive. The center or origin of the image is at (0, 0). One Leonardo co-ordinate corresponds to one pixel on the screen if your image is zoomed to 100% (i.e.: zoom level 0).
As far as Leonardo is concerned, there are 256 "degrees" in a circle, as opposed to the more widely used 360 degrees. However, when using Leonardo itself, degrees are represented in their normal range (0 - 359) in the user interface, so users will understand what is going on. 0 - 255 is Leonardo's internal representation which has the advantage of only occupying one byte of memory. This provides lower memory consumption than would be possible with 360 degrees (which would require two bytes) and allows Leonardo to perform calculations on angles more efficiently than it would otherwise. Looking at a circle front-on, Leonardo angles start at 0 at the topmost point of the circle then move clockwise as shown in the diagram below.
If you need to convert a Leonardo angle to degrees, multiply by 1.40625. Here's a handy conversion table for common angles:
| Degrees | LeoAngle |
|---|---|
| 0° | 0 |
| 45° | 32 |
| 90° | 64 |
| 135° | 96 |
| 180° | 128 |
| 225° | 160 |
| 270° | 192 |
| 315° | 224 |
All colors are represented by a hexadecimal index in the range 0x00 to 0xe9 depending on the palette type of the image, which can be 1, 2, 4 or 8 bits per pixel. Following is a mapping of Leonardo color indices to HTML RGB values:
| 0x00 | #ffffff | 0x01 | #000000 |
|---|
| 0x00 | #ffffff | 0x01 | #888888 | 0x02 | #444444 | 0x03 | #000000 |
|---|
| 0x00 | #ffffff | 0x01 | #eeeeee | 0x02 | #dddddd | 0x03 | #cccccc | 0x04 | #bbbbbb | 0x05 | #aaaaaa | 0x06 | #999999 | 0x07 | #888888 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0x08 | #777777 | 0x09 | #666666 | 0x0a | #555555 | 0x0b | #444444 | 0x0c | #333333 | 0x0d | #222222 | 0x0e | #111111 | 0x0f | #000000 |
Note that the entire possible set of 256 palette entries is not visible in Leonardo - the palette display in Leonardo only goes up to 0xe9. The remaining 21 palette entries all map to black, but this may not necessarily be true in future.
| 0x00 | #ffffff | 0x01 | #ffccff | 0x02 | #ff99ff | 0x03 | #ff66ff | 0x04 | #ff33ff | 0x05 | #ff00ff |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 0x06 | #ffffcc | 0x07 | #ffcccc | 0x08 | #ff99cc | 0x09 | #ff66cc | 0x0a | #ff33cc | 0x0b | #ff00cc |
| 0x0c | #ffff99 | 0x0d | #ffcc99 | 0x0e | #ff9999 | 0x0f | #ff6699 | 0x10 | #ff3399 | 0x11 | #ff0099 |
| 0x12 | #ccffff | 0x13 | #ccccff | 0x14 | #cc99ff | 0x15 | #cc66ff | 0x16 | #cc33ff | 0x17 | #cc00ff |
| 0x18 | #ccffcc | 0x19 | #cccccc | 0x1a | #cc99cc | 0x1b | #cc66cc | 0x1c | #cc33cc | 0x1d | #cc00cc |
| 0x1e | #ccff99 | 0x1f | #cccc99 | 0x20 | #cc9999 | 0x21 | #cc6699 | 0x22 | #cc3399 | 0x23 | #cc0099 |
| 0x24 | #99ffff | 0x25 | #99ccff | 0x26 | #9999ff | 0x27 | #9966ff | 0x28 | #9933ff | 0x29 | #9900ff |
| 0x2a | #99ffcc | 0x2b | #99cccc | 0x2c | #9999cc | 0x2d | #9966cc | 0x2e | #9933cc | 0x2f | #9900cc |
| 0x30 | #99ff99 | 0x31 | #99cc99 | 0x32 | #999999 | 0x33 | #996699 | 0x34 | #993399 | 0x35 | #990099 |
| 0x36 | #66ffff | 0x37 | #66ccff | 0x38 | #6699ff | 0x39 | #6666ff | 0x3a | #6633ff | 0x3b | #6600ff |
| 0x3c | #66ffcc | 0x3d | #66cccc | 0x3e | #6699cc | 0x3f | #6666cc | 0x40 | #6633cc | 0x41 | #6600cc |
| 0x42 | #66ff99 | 0x43 | #66cc99 | 0x44 | #669999 | 0x45 | #666699 | 0x46 | #663399 | 0x47 | #660099 |
| 0x48 | #33ffff | 0x49 | #33ccff | 0x4a | #3399ff | 0x4b | #3366ff | 0x4c | #3333ff | 0x4d | #3300ff |
| 0x4e | #33ffcc | 0x4f | #33cccc | 0x50 | #3399cc | 0x51 | #3366cc | 0x52 | #3333cc | 0x53 | #3300cc |
| 0x54 | #33ff99 | 0x55 | #33cc99 | 0x56 | #339999 | 0x57 | #336699 | 0x58 | #333399 | 0x59 | #330099 |
| 0x5a | #00ffff | 0x5b | #00ccff | 0x5c | #0099ff | 0x5d | #0066ff | 0x5e | #0033ff | 0x5f | #0000ff |
| 0x60 | #00ffcc | 0x61 | #00cccc | 0x62 | #0099cc | 0x63 | #0066cc | 0x64 | #0033cc | 0x65 | #0000cc |
| 0x66 | #00ff99 | 0x67 | #00cc99 | 0x68 | #009999 | 0x69 | #006699 | 0x6a | #003399 | 0x6b | #000099 |
| 0x6c | #ffff66 | 0x6d | #ffcc66 | 0x6e | #ff9966 | 0x6f | #ff6666 | 0x70 | #ff3366 | 0x71 | #ff0066 |
| 0x72 | #ffff33 | 0x73 | #ffcc33 | 0x74 | #ff9933 | 0x75 | #ff6633 | 0x76 | #ff3333 | 0x77 | #ff0033 |
| 0x78 | #ffff00 | 0x79 | #ffcc00 | 0x7a | #ff9900 | 0x7b | #ff6600 | 0x7c | #ff3300 | 0x7d | #ff0000 |
| 0x7e | #ccff66 | 0x7f | #cccc66 | 0x80 | #cc9966 | 0x81 | #cc6666 | 0x82 | #cc3366 | 0x83 | #cc0066 |
| 0x84 | #ccff33 | 0x85 | #cccc33 | 0x86 | #cc9933 | 0x87 | #cc6633 | 0x88 | #cc3333 | 0x89 | #cc0033 |
| 0x8a | #ccff00 | 0x8b | #cccc00 | 0x8c | #cc9900 | 0x8d | #cc6600 | 0x8e | #cc3300 | 0x8f | #cc0000 |
| 0x90 | #99ff66 | 0x91 | #99cc66 | 0x92 | #999966 | 0x93 | #996666 | 0x94 | #993366 | 0x95 | #990066 |
| 0x96 | #99ff33 | 0x97 | #99cc33 | 0x98 | #999933 | 0x99 | #996633 | 0x9a | #993333 | 0x9b | #990033 |
| 0x9c | #99ff00 | 0x9d | #99cc00 | 0x9e | #999900 | 0x9f | #996600 | 0xa0 | #993300 | 0xa1 | #990000 |
| 0xa2 | #66ff66 | 0xa3 | #66cc66 | 0xa4 | #669966 | 0xa5 | #666666 | 0xa6 | #663366 | 0xa7 | #660066 |
| 0xa8 | #66ff33 | 0xa9 | #66cc33 | 0xaa | #669933 | 0xab | #666633 | 0xac | #663333 | 0xad | #660033 |
| 0xae | #66ff00 | 0xaf | #66cc00 | 0xb0 | #669900 | 0xb1 | #666600 | 0xb2 | #663300 | 0xb3 | #660000 |
| 0xb4 | #33ff66 | 0xb5 | #33cc66 | 0xb6 | #339966 | 0xb7 | #336666 | 0xb8 | #333366 | 0xb9 | #330066 |
| 0xba | #33ff33 | 0xbb | #33cc33 | 0xbc | #339933 | 0xbd | #336633 | 0xbe | #333333 | 0xbf | #330033 |
| 0xc0 | #33ff00 | 0xc1 | #33cc00 | 0xc2 | #339900 | 0xc3 | #336600 | 0xc4 | #333300 | 0xc5 | #330000 |
| 0xc6 | #00ff66 | 0xc7 | #00cc66 | 0xc8 | #009966 | 0xc9 | #006666 | 0xca | #003366 | 0xcb | #000066 |
| 0xcc | #00ff33 | 0xcd | #00cc33 | 0xce | #009933 | 0xcf | #006633 | 0xd0 | #003333 | 0xd1 | #000033 |
| 0xd2 | #00ff00 | 0xd3 | #00cc00 | 0xd4 | #009900 | 0xd5 | #006600 | 0xd6 | #003300 | 0xd7 | #111111 |
| 0xd8 | #222222 | 0xd9 | #444444 | 0xda | #555555 | 0xdb | #777777 | 0xdc | #888888 | 0xdd | #aaaaaa |
| 0xde | #bbbbbb | 0xdf | #dddddd | 0xe0 | #eeeeee | 0xe1 | #c0c0c0 | 0xe2 | #800000 | 0xe3 | #800080 |
| 0xe4 | #008000 | 0xe5 | #008080 | 0xe6 | #000000 | 0xe7 | #000000 | 0xe8 | #000000 | 0xe9 | #000000 |
There are seven different types of object (or shape) that Leonardo is aware of: arc, ellipse, bezier, rectangle, polyline, polygon and text. Following is a mapping of Leonardo drawing tools to actual Leonardo objects, to provide a point of reference. Some object flags are mentioned - the specifics of these are covered elsewhere in this document.
| Drawing Tool | Actual Object Created |
|---|---|
| Bezier Tool | bezier |
| Arc Tool | arc |
| Straight Line Tool | polyline (2 points, freehand = false) |
| Polyline Tool | polyline (n points, freehand = false) |
| Freehand Tool | polyline (n points, freehand = true) |
| Marker Tools | Manipulate bezier/arc/polyline properties |
| Polygon Tool | polygon (n points) |
| Isosceles Triangle Tool | polygon (3 points) |
| Right Angle Triangle Tool | polygon (3 points) |
| Square Tool | rectangle |
| Rectangle Tool | rectangle |
| Circle Tool | ellipse |
| Ellipse Tool | ellipse |
| Small Text Tool | text (8 point) |
| Medium Text Tool | text (8 point, bold) |
| Large Text Tool | text (10 point, bold) |
If you have installed the conduit that comes with Leonardo's Workshop, when you hotsync your PDA, your Leonardo images will be converted to Leonardo image files in the c:\Palm\USERNAME\Leonardo folder. Likewise, any Leonardo image files in this folder will be synched back to your PDA. The images are in an XML format, described below. Because they are XML files, they can be edited by hand using a text editor. Programs can also be written relatively easily to manipulate and convert Leonardo images in this XML format.
For reasons of speed and size, Leonardo itself works directly with Palm databases, in a binary format. This binary format is not described in this document, although it is conceptually similar to the XML format. Note that this means the backup PDB files in your c:\Palm\USERNAME\Backup folder are not in the Leonardo XML format.
As you go through this document, it may be helpful to have a Leonardo image open in a text editor.
Because this is an XML file, the first line of the file must be the usual <?xml version="1.0"?> processing instruction. Following this, the root element is leonardoImage. Inside the leonardoImage element are the dbName, origin and objects elements. Finally, inside the objects element are the actual objects that make up the image, one after another.
The leonardoImage element has the following attributes:
| Name | Description | Valid values |
|---|---|---|
| bgColor | Color index of image background color. | 0x00 - 0xe9 |
| lastModified | Timestamp for when the image was last modified, expressed as the number of seconds since the first instant of January 1, 1904. | 0xnnnnnnnn |
| paletteType | Bits per pixel in palette. | 1, 2, 4 or 8 |
| version | Image file format version | 1.0 |
| zoomFactor | Current zoom level for display in Leonardo (0 = 100% or 1:1 zoom) | -101 to 9 |
The dbName element contains the name of the corresponding Leonardo image database on the PDA. Image database names are in the form "wLeoname", where name is the image name as displayed to the user. The name portion can be a maximum of 27 characters.
The origin element is an empty element (i.e.: it has no children) which specifies the current position of the center of the Leonardo viewport relative to the center of the image itself (the specifics of the attributes are defined below).
As mentioned previously, the objects element contains all the objects that make up the image, one after another. For display purposes, the first object listed in the file is the rear-most and the last object in the file is the front-most.
Here's an example snippet:
<?xml version="1.0"?> <leonardoImage bgColor="0x04" lastModified="0xba23857f" paletteType="4" version="1.0" zoomFactor="-62"> <dbName><![CDATA[wLeountitled]]></dbName> <origin x="0" y="0"/> <objects> <polyline freehand="false"> <-- polyline data here --> </polyline> <-- more objects here --> </objects> </leonardoImage>
In various places in Leonardo image files, there is a need to specify the co-ordinates of a vertex, or a size. The elements used for this have different names depending on their context, but they all share the same basic form; they are empty elements with an X and a Y attribute. These elements are:
The origin element specifies the center (origin) of an object. It has the following attributes:
| Name | Description | Valid values |
|---|---|---|
| x | X co-ordinate | -32768 - 32767 |
| y | Y co-ordinate | -32768 - 32767 |
The v element specifies the position of an individual vertex in a polyline, polygon or bezier. It has the following attributes:
| Name | Description | Valid values |
|---|---|---|
| x | X co-ordinate | -32768 - 32767 |
| y | Y co-ordinate | -32768 - 32767 |
The entire list of vertices that make up a polyline, polygon or bezier are defined in the points element as a list of v elements, for example:
<points>
<v x="-6" y="-13"/>
<v x="-8" y="-12"/>
<v x="-9" y="-9"/>
</points>
The maximum number of points in any object is 500.
The topLeft element specifies the top left co-ordinate of a rectangular area. It has the following attributes:
| Name | Description | Valid values |
|---|---|---|
| x | X co-ordinate | -32768 - 32767 |
| y | Y co-ordinate | -32768 - 32767 |
The bottomRight element specifies the bottom right co-ordinate of a rectangular area. It has the following attributes:
| Name | Description | Valid values |
|---|---|---|
| x | X co-ordinate | -32768 - 32767 |
| y | Y co-ordinate | -32768 - 32767 |
The extent element specifies the width and height of a rectangular area. It has the following attributes:
| Name | Description | Valid values |
|---|---|---|
| x | Width | -32768 - 32767 |
| y | Height | -32768 - 32767 |
The radius element is effectively the same as extent but is used when defining the X and Y radius of an ellipse. It's attributes are:
| Name | Description | Valid values |
|---|---|---|
| x | X Radius | -32768 - 32767 |
| y | Y Radius | -32768 - 32767 |
The bounds element defines a rectangular bounding box. It has no attributes, but instead includes a topLeft and an extent element. For example:
<bounds>
<topLeft x="-9" y="-13"/>
<extent x="55" y="25"/>
</bounds>
This defines an area 55 pixels by 25 pixels, whose top left corner is at (-9, -13).
Arcs, beziers and polylines can have markers attached to their ends. Each of these objects includes a marker element to specify the markers used. It is an empty element with the following attributes:
| Name | Description | Valid values |
|---|---|---|
| start | Marker at start of line | "none", "circle", "square" or "triangle" |
| end | Marker at end of line | "none", "circle", "square" or "triangle" |
Each object in a Leonardo image includes a style element which defines the stroke, fill and position of the object. It has the following attributes:
| Name | Description | Valid values |
|---|---|---|
| visible | Object is visible [N/I] | "true" or "false" |
It includes as children origin, bounds, stroke and fill elements. Here's an example:
<style visible="true">
<origin x="-55" y="-41"/>
<bounds>
<topLeft x="-64" y="-54"/>
<extent x="19" y="26"/>
</bounds>
<stroke color="0xe9" type="solid" width="1"/>
<fill color="0x00"/>
</style>
The stroke element defines the stroke width, color and style for an object. It is an empty element with the following attributes:
| Name | Description | Valid values |
|---|---|---|
| type | Stroke style | "solid", "dot" or "dash" |
| width | Stroke width | 0 - 99 |
| color | Stroke color | 0x00 - 0xe9 |
If the stroke width is zero, the line is considered to be infinitely thin - it will always be rendered one pixel wide regardless of how far you zoom in. The idea is that these magic thin lines can be used for guides when drawing, for example.
The fill element defines the fill style of an object. Fills can be either solid, a texture or a gradient. The exact structure of the fill element varies depending on this type. For a solid fill, the fill element is empty, and has one attribute - color - specifying the color to use. Here's an example:
<fill color="0x00"/>
For a texture fill, the fill element has no attributes, but includes a texture element as its only child.
For a gradient fill, the fill element has no attributes, but includes a gradient element as its only child.
The texture element includes a pattern element which defines a bitmask for the texture as a long hexadecimal number. The texture element has the following attributes:
| Name | Description | Valid values |
|---|---|---|
| fgColor | Foreground color of bitmask | 0x00 - 0xe9 |
| bgColor | Background color of bitmask | 0x00 - 0xe9 |
Here's an example texture fill:
<fill>
<texture bgColor="0x00" fgColor="0xe9">
<pattern><![CDATA[0x004020100a060e00]]></pattern>
</texture>
</fill>
The hex number inside the pattern element defines an eight-byte bitmask (an 8x8 grid). In this case, the pattern is:
| 00 | ||||||||
| 40 | ||||||||
| 20 | ||||||||
| 10 | ||||||||
| 0a | ||||||||
| 06 | ||||||||
| 0e | ||||||||
| 00 |
The gradient element is an empty element with the following attributes:
| Name | Description | Valid values |
|---|---|---|
| type | Gradient type | "linear" or "radial" |
| angle | Angle for linear gradient | 0 - 255 |
| color1 | Gradient from this color... | 0x00 - 0xe9 |
| color2 | ...to this color | 0x00 - 0xe9 |
Here's an example gradient fill:
<fill>
<gradient color2="0x00" type="linear" angle="32" color1="0xe9"/>
</fill>
For example (using a rectangle):
<rectangle angle="0">
<style visible="true">
<origin x="18" y="-1"/>
<bounds>
<topLeft x="-9" y="-13"/>
<extent x="55" y="25"/>
</bounds>
<stroke color="0x4f" type="solid" width="1"/>
<fill color="0x00"/>
</style>
<topLeft x="-27" y="-12"/>
<bottomRight x="27" y="12"/>
</rectangle>
It is very important that when manipulating object co-ordinates (relative to the object's origin) that the object bounds (relative to the center of the image) are kept up to date. The bounds must be the smallest image-relative rectangle that contains all the vertices that make up the object. If the bounds are set incorrectly, the image will not view correctly in Leonardo. The bounds element will ultimately be removed in a later version of Leonardo's Workshop, as it is technically redundant data, and because it can cause this problem if manipulated incorrectly. However, for now, it must be maintained. To sum up:
The arc element defines an elliptical arc. It contains three children: style, radius for the X and Y radius of the arc and marker for the markes to use at the ends of the arc. It has the following attributes:
| Name | Description | Valid values |
|---|---|---|
| angle | Rotation angle [N/I] | 0 - 255 |
| start | Angle at which the arc starts | 0 - 255 |
| end | Angle at which the arc ends | 0 - 255 |
Here's an example:
<arc angle="0" end="192" start="64">
<style visible="true">
<origin x="-21" y="-41"/>
<bounds>
<topLeft x="-29" y="-41"/>
<extent x="17" y="18"/>
</bounds>
<stroke color="0xe9" type="solid" width="1"/>
<fill color="0x00"/>
</style>
<radius x="8" y="17"/>
<marker end="none" start="none"/>
</arc>
The ellipse element has two children: style and radius for the X and Y radius of the ellipse. It has the following attributes:
| Name | Description | Valid values |
|---|---|---|
| angle | Rotation angle [N/I] | 0 - 255 |
Here's an example:
<ellipse angle="0">
<style visible="true">
<origin x="46" y="18"/>
<bounds>
<topLeft x="25" y="4"/>
<extent x="43" y="29"/>
</bounds>
<stroke color="0xe9" type="solid" width="1"/>
<fill color="0x7d"/>
</style>
<radius x="21" y="14"/>
</ellipse>
The bezier element defines a cubic Bézier curve. It has no attributes, but has three children: style, marker and points. There must be exactly four points defined for the bezier - Leonardo won't draw beziers with more or less points than this. Here's an example:
<bezier>
<style visible="true">
<origin x="-43" y="46"/>
<bounds>
<topLeft x="-56" y="27"/>
<extent x="26" y="38"/>
</bounds>
<stroke color="0xe9" type="solid" width="1"/>
<fill color="0x00"/>
</style>
<marker end="none" start="none"/>
<points>
<v x="-13" y="-7"/>
<v x="-1" y="-19"/>
<v x="0" y="18"/>
<v x="12" y="6"/>
</points>
</bezier>
The ellipse element has three children: style, topLeft and bottomRight. The latter two children define the corners of the rectangle. It has the following attributes:
| Name | Description | Valid values |
|---|---|---|
| angle | Rotation angle [N/I] | 0 - 255 |
Here's an example:
<rectangle angle="0">
<style visible="true">
<origin x="18" y="-1"/>
<bounds>
<topLeft x="-9" y="-13"/>
<extent x="55" y="25"/>
</bounds>
<stroke color="0x4f" type="solid" width="1"/>
<fill color="0x00"/>
</style>
<topLeft x="-27" y="-12"/>
<bottomRight x="27" y="12"/>
</rectangle>
The polyline element has three children: style, marker and points. It can have between 2 and 500 points. It has the following attributes:
| Name | Description | Valid values |
|---|---|---|
| freehand | If freehand, points cannot be manipulated in Leonardo. | "true" or "false" |
Here's an example:
The polygon element has two children: style and points. It can have between 3 and 500 points. It has no attributes. Here's an example:
<polygon>
<style visible="true">
<origin x="-3" y="24"/>
<bounds>
<topLeft x="-25" y="9"/>
<extent x="45" y="30"/>
</bounds>
<stroke color="0xe9" type="solid" width="1"/>
<fill color="0x7d"/>
</style>
<points>
<v x="0" y="-15"/>
<v x="-22" y="14"/>
<v x="22" y="14"/>
</points>
</polygon>
The text element has five children: style, topLeft, bottomRight, flags and string. It has the following attributes:
| Name | Description | Valid values |
|---|---|---|
| angle | Rotation angle [N/I] | 0 - 255 |
| size | Point size of text | 8 or 10 |
| font | Font index [N/I] | 0xnnnnnnnn |
Note that the point size can in theory be from 1 - 255, but Leonardo will only render 8 or 10 point text as of this writing.
The topLeft and bottomRight elements specify the corners of the rectangle containing the text. The flags element specifies various font effects and has the following attributes:
| Name | Description | Valid values |
|---|---|---|
| hidden | Text is minimized | "true" or "false" |
| bold | Font is bold | "true" or "false" |
| italic | Font is italic [N/I] | "true" or "false" |
| underlined | Font is underlined [N/I] | "true" or "false" |
The string element contains the text itself. Here's an example:
<text angle="0" font="0x00" size="8">
<style visible="true">
<origin x="3" y="-4"/>
<bounds>
<topLeft x="-43" y="-49"/>
<extent x="94" y="112"/>
</bounds>
<stroke color="0xe9" type="solid" width="1"/>
<fill color="0x7d"/>
</style>
<topLeft x="-46" y="-45"/>
<bottomRight x="47" y="66"/>
<flags bold="true" hidden="false" italic="false" underlined="false"/>
<string><![CDATA[This is a block of text consisting of a few paragraphs.
Here's the second paragraph.
Foo
Bar
Baz]]></string>
</text>
The Leonardo XML format serves well to represent anything you can possibly create in Leonardo, and is reasonably human-readable. However there are some issues that will be addressed in a future version of the file format. These are: