Skip to content

Chapter 4: Basic figures lines and shapes

4.1. Rect, circle and ellipse

As well as allowing you to place text on the page, pageGraphics also allows you to place shapes and graphics on it.

The basic types of shape that RML allows you to use are:

rect (rectangle), circle, and ellipse.

A rect needs to have a list of attributes passed to it:

  • the co-ordinates for the bottom left hand corner,
  • its width and height,

It also has optional fill and stroke attributes, and a round attribute, which tell it if the corners should be rounded off.

The circle needs the following attributes passed to it:

  • the x and y co-ordinates of the point where its center should be,
  • its radius

If you imagine the ellipse inside a rectangle, the x and y attributes give the co-ordinates for the bottom left hand corner, and the width and height attributes give the co-ordinates for the top right hand corner of the box.

All shapes also have two optional attributes:

  • fill, which tells the parser if the shape should be filled in or not, and
  • stroke which tells it if the shape should have its outline displayed.

Both these attributes take Boolean values as arguments. You can uses either "1" or "yes" to set them as on, or "0" or "no" to set them as off.

The following example shows various combinations of attributes for each of the basic shapes. Notice how this example starts with the XML definition - you can get away with not using it, but it is still better to make sure it is there.

EXAMPLE 3

<?xml version="1.0" encoding="iso-8859-1" standalone="no" ?>
<!DOCTYPE document SYSTEM "../rml.dtd">
<document filename="example_3.pdf">
<template>
    <pageTemplate id="main">
        <pageGraphics>
            <!-- set the font and fill colour for the title. -->
            <fill color="red"/>
            <setFont name="Helvetica" size="24"/>
            <!-- Use drawCentredString to place a title on the page -->
            <drawCentredString x="297.5" y="800">Simple Text and Graphics with RML.</drawCentredString>
            <fill color="red"/>
            <!-- look at the output - though a fill color is set, no fill is produced, -->
            <!-- since fill is set to "no" for the circle -->
            <circle x="127.5" y="672.75" radius="1 in" fill="no" stroke="yes"/>
            <fill color="green"/>
            <stroke color="black"/>
            <circle x="297.5" y="672.75" radius="1 in" fill="yes" stroke="no"/>
            <fill color="blue"/>
            <stroke color="black"/>
            <circle x="467.5" y="672.75" radius="1 in" fill="yes" stroke="yes"/>
            <fill color="black"/>
            <setFont name="Helvetica" size="9"/>
            <drawCentredString x="127.5" y="567.5">Circle - with stroke, but no fill.</drawCentredString>
            <drawCentredString x="297.5" y="567.5">Circle - with fill, but no stroke.</drawCentredString>
            <drawCentredString x="467.5" y="567.5">Circle - with both stroke and fill.</drawCentredString>
            <fill color="red"/>
            <ellipse x="77" y="382.25" width="110" height="170" fill="no" stroke="yes"/>
            <fill color="green"/>
            <stroke color="black"/>
            <ellipse x="247" y="382.25" width="110" height="170" fill="yes" stroke="no"/>
            <fill color="blue"/>
            <stroke color="black"/>
            <ellipse x="417" y="382.25" width="110" height="170" fill="yes" stroke="yes"/>
            <fill color="black"/>
            <drawCentredString x="127.5" y="357">Ellipse - with stroke, but no fill.</drawCentredString>
            <drawCentredString x="297.5" y="357">Ellipse - with fill, but no stroke.</drawCentredString>
            <drawCentredString x="467.5" y="357">Ellipse - with both stroke and fill.</drawCentredString>
            <rect x="84.5" y="214.3" width="1 in" height="1.15 in" fill="no" stroke="yes"/>
            <fill color="green"/>
            <stroke color="black"/>
            <rect x="254.5" y="214.3" width="1 in" height="1.15 in" fill="yes" stroke="no"/>
            <fill color="blue"/>
            <stroke color="black"/>
            <rect x="424.5" y="214.3" width="1 in" height="1.15 in" fill="yes" stroke="yes"/>
            <fill color="black"/>
            <drawCentredString x="127.5" y="199.1">Rect - with stroke, but no fill.</drawCentredString>
            <drawCentredString x="297.5" y="199.1">Rect - with fill, but no stroke.</drawCentredString>
            <drawCentredString x="467.5" y="199.1">Rect - with both stroke and fill.</drawCentredString>
            <rect x="84.5" y="56.5" width="1 in" height="1.15 in" fill="no" stroke="yes" round="0.15 in"/>
            <fill color="green"/>
            <stroke color="black"/>
            <rect x="254.5" y="56.5" width="1 in" height="1.15 in" fill="yes" stroke="no" round="0.15 in"/>
            <fill color="blue"/>
            <stroke color="black"/>
            <rect x="424.5" y="56.5" width="1 in" height="1.15 in" fill="yes" stroke="yes" round="0.15 in"/>
            <fill color="black"/>
            <drawCentredString x="127.5" y="41.25">Rect - with stroke and round, but no fill.</drawCentredString>
            <drawCentredString x="297.5" y="41.25">Rect - with fill and round, but no stroke.</drawCentredString>
            <drawCentredString x="467.5" y="41.25">Rect - with stroke, fill and round.</drawCentredString>
        </pageGraphics>
         <frame id="first" x1="0.5in" y1="0.5in" width="20cm" height="28cm"/>
    </pageTemplate>
</template>
<stylesheet>
</stylesheet>
<story>
<para></para>
</story>
</document>

Figure 3: Output from EXAMPLE 3

4.2. Fill and stroke

If you look at the example 3, you will see that as well as having fill and stroke attributes for the shapes, there are separate <fill> and <stroke> tags.

Inside the tag for a shape (such as rect), fill and stroke simply tell rml2pdf whether those qualities should be turned on. Should there be a fill, or not? Should there be a stroke, or not? That is why the argument is Boolean - "yes" or "no" (though "1" or "0" are also allowed).

The fill and stroke tags do a different job. The only argument that these tags are allowed is a color. If there are no fill or stroke tags in a document, both the fill and the stroke for all shapes default to black. If you have a fill tag before a shape, it allows you to change the color that that shape is filled with. Similarly, a stroke tag before a shape allows you to set the color that the outline of that shape will be drawn in. If there is no fill or stroke tag in front of a shape, it will be filled and stroked with the most recently defined fill or stroke - or failing that, the default black.

This means that you can use one fill tag to refer to many shapes, while changing the stroke for each of them. Or vice versa.

Another brief example of how the fill and stroke tags look:

<fill color="olivedrab"/>
<stroke color="khaki"/>

4.3. Lines and lineMode

The other basic drawing element is the line. To draw a simple line, you use the <lines> tag. For each line you want to draw, you pass <lines> two pairs of X-Y co-ordinates - one pair of co-ordinates for the start point of the line, the other for the end point.

If you want to draw more than one line, you can keep passing <lines> more sets of 4 co-ordinates. <lines> then draws those other separate lines on the page. The lines in a <lines> command are just lumped together in one <lines> tag for your convenience. (If you want lines that follow on from each other, look at the "Advanced figures" section later in this manual).

For example, this draws a simple line:

<lines>
    2.5in 10.5in 3.5in 10.5in
</lines>

And this starts with the same line, then draws an extra couple of lines below it:

<lines>
    2.5in 10.5in 3.5in 10.5in
    2.5in 10.25in 3.5in 10.25in
    2.5in 10in 3.5in 10in
</lines>

It doesn't matter how you arrange the sets of co-ordinates, but it helps to keep it human-readable if you keep co-ordinates to do with the same line on the same line of RML. This second example could have been written like this (but it would be much harder to follow):

<lines>
    2.5in 10.5in 3.5in 10.5in 2.5in 10.25in 3.5in 10.25in 2.5in 10in 3.5in 10in
</lines>

One more thing to notice before we move on is that these co-ordinates are separated by spaces. They are not separated by commas as you might expect.

As well as just drawing lines, there are a number of attributes you can modify to change the appearance of lines. This is done with the <lineMode> tag.

The most obvious attribute to <lineMode> is width. You can give <lineMode> a number for the width attribute to change the line width to that number of points.

Figure 4: Example of lineMode attribute "width"

The join attribute to <lineMode> adjusts how what happens when lines meet. They can either come to a point, or the vertex can be rounded or squared off into a bevelled join. The possible values for join are round, mitered, or bevelled.

The cap attribute to <lineMode> adjusts how the ends of lines appear. The end of a line can have a square end exactly at the vertex, a square end that is extended so it is over the vertex, or a half circle - a rounded cap. These possible values for cap are default, square or round.

Figure 5: Example of lineMode attribute "cap"

Both the join and cap attributes for <lineMode> are only really visible if the line you are applying them to is thick.

Another attribute to <lineMode> is dash. This allows you to specify if the line is dotted or dashed. You supply it a series of numbers (separated by commas), and it takes them as a pattern for how many pixels the line is on for, and then how many pixels the line is off (i.e. not displayed) for. This can be a simple pattern such as "1,2" (which gives you a plain dotted line) or "5,5" (which makes the lines sections equal with the spaces), or as complex as "1,1,3,3,1,4,4,1" (a complex pattern of dots and dashes).

Figure 6: Example of lineMode attribute "dash"

The following example shows examples of most of the attributes that you can use with <lines> and <lineMode>. Notice how you can use more that one attribute to <lineMode> at the same time.

EXAMPLE 4

<?xml version="1.0" encoding="iso-8859-1" standalone="no" ?> 
<!DOCTYPE document SYSTEM "../rml.dtd"> 
<document filename="example_4.pdf">

<template>
    <pageTemplate id="main">
    <pageGraphics>

        <fill color="red"/>

        <setFont name="Helvetica" size="24"/>
        <drawCentredString x="297.5" y="800">Lines in RML.</drawCentredString>

        <!-- notice that each of these "empty" tags are teminated with a slash -->
        <lineMode width="1"/>
        <lines>1in 10.5in 2in 10.5in 
        2in 10.5in 1.5in 10in
        1.5in 10in 1.5in 10.75in
        </lines>
        <fill color="black"/>
        <setFont name="Helvetica" size="9"/>
        <drawCentredString x="1.5 in" y="9.75 in">width = 1</drawCentredString>

        <lineMode width="5"/>
        <lines>2.5in 10.5in 3.5in 10.5in 
        3.5in 10.5in 3in 10in
        3in 10in 3in 10.75in
        </lines>
        <drawCentredString x="3 in" y="9.75 in">width = 5</drawCentredString>

        <lineMode width="10"/>
        <lines>4in 10.5in 5in 10.5in 
        5in 10.5in 4.5in 10in
        4.5in 10in 4.5in 10.75in
        </lines>
        <drawCentredString x="4.5 in" y="9.75 in">width = 10</drawCentredString>

        <lineMode width="15"/>
        <lines>5.5in 10.5in 6.5in 10.5in 
        6.5in 10.5in 6in 10in
        6in 10in 6in 10.75in
        </lines>
        <drawCentredString x="6 in" y="9.75 in">width = 15</drawCentredString>

         <!-- examples for the 'join' attribute to 'LineMode' -->
        <lineMode width="5"/>
        <lines>1in 9in 2in 9in 
        2in 9in 1.5in 8.5in
        1.5in 8.5in 1.5in 9.25in
        </lines>
        <fill color="black"/>
        <setFont name="Helvetica" size="9"/>
        <drawCentredString x="1.5 in" y="8.25 in">width=10</drawCentredString>

        <!-- options for 'join' are "round", "mitered", or "bevelled" -->

        <lineMode width="5" join="round"/>
        <lines>2.5in 9in 3.5in 9in 
        3.5in 9in 3in 8.5in
        3in 8.5in 3in 9.25in
        </lines>
        <drawCentredString x="3 in" y="8.25 in">width=5, join=round</drawCentredString>

        <lineMode width="5" join="mitered"/>
        <lines>4in 9in 5in 9in 
        5in 9in 4.5in 8.5in
        4.5in 8.5in 4.5in 9.25in
        </lines>
        <drawCentredString x="4.5 in" y="8.25 in">width=5, join=mitered</drawCentredString>

        <lineMode width="5" join="bevelled"/>
        <lines>5.5in 9in 6.5in 9in 
        6.5in 9in 6in 8.5in
        6in 8.5in 6in 9.25in
        </lines>
        <drawCentredString x="6 in" y="8.25 in">width=5, join=bevelled</drawCentredString>

        <!-- examples for the 'cap' attribute to 'LineMode' -->
        <lineMode width="10"/>
        <lines>1in 7.5in 2in 7.5in 
        2in 7.5in 1.5in 7in
        1.5in 7in 1.5in 7.75in
        </lines>
        <fill color="black"/>
        <setFont name="Helvetica" size="9"/>
        <drawCentredString x="1.5 in" y="6.75 in">width=10</drawCentredString>

        <!-- options for 'cap' are "default", "round", or "square" -->

        <lineMode width="10" cap="default"/>
        <lines>2.5in 7.5in 3.5in 7.5in 
        3.5in 7.5in 3in 7in
        3in 7in 3in 7.75in
        </lines>
        <drawCentredString x="3 in" y="6.75 in">width=10, cap=default</drawCentredString>

        <lineMode width="10" cap="round"/>
        <lines>4in 7.5in 5in 7.5in 
        5in 7.5in 4.5in 7in
        4.5in 7in 4.5in 7.75in
        </lines>
        <drawCentredString x="4.5 in" y="6.75 in">width=10, cap=round</drawCentredString>

        <lineMode width="10" cap="square"/>
        <lines>5.5in 7.5in 6.5in 7.5in 
        6.5in 7.5in 6in 7in
        6in 7in 6in 7.75in
        </lines>
        <drawCentredString x="6 in" y="6.75 in">width=10, cap=square</drawCentredString>

        <lineMode width="5" cap="default"/>
        <!-- examples for the 'miterLimit' attribute to 'LineMode' -->
        <lineMode width="5" join="mitered"/>
        <lines>1in 6in 2in 6in 
        2in 6in 1.5in 5.5in
        1.5in 5.5in 1.5in 6.25in
        </lines>
        <fill color="black"/>
        <setFont name="Helvetica" size="9"/>
        <drawCentredString x="1.5 in" y="5.25 in">width=5, join=mitered</drawCentredString>

        <lineMode width="5" join="mitered" miterLimit="10"/>
        <lines>2.5in 6in 3.5in 6in 
        3.5in 6in 3in 5.5in
        3in 5.5in 3in 6.25in
        </lines>
        <drawCentredString x="3 in" y="5.25 in">width=5, join=mitered</drawCentredString>
        <drawCentredString x="3 in" y="5.1 in">miterLimit=10</drawCentredString>

        <lineMode width="10" join="mitered"/>
        <lines>4in 6in 5in 6in 
        5in 6in 4.5in 5.5in
        4.5in 5.5in 4.5in 6.25in
        </lines>
        <drawCentredString x="4.5 in" y="5.25 in">width=10, join=mitered</drawCentredString>

        <lineMode width="10" join="mitered" miterLimit="20"/>
        <lines>5.5in 6in 6.5in 6in 
        6.5in 6in 6in 5.5in
        6in 5.5in 6in 6.25in
        </lines>
        <drawCentredString x="6 in" y="5.25 in">width=10, join=mitered</drawCentredString>
        <drawCentredString x="6 in" y="5.1 in">miterLimit=20</drawCentredString>

        <!-- examples for the 'dash' attribute to 'LineMode' -->
        <lineMode width="2"/>
        <lines>1in 4.5in 2in 4.5in 
        2in 4.5in 1.5in 4in
        1.5in 4in 1.5in 4.75in
        </lines>
        <fill color="black"/>
        <setFont name="Helvetica" size="9"/>
        <drawCentredString x="1.5 in" y="3.75 in">width=2</drawCentredString>

        <!-- options for 'dash' are sequences of numbers -->

        <lineMode width="2" dash="5,5"/>
        <lines>2.5in 4.5in 3.5in 4.5in 
        3.5in 4.5in 3in 4in
        3in 4in 3in 4.75in
        </lines>
        <drawCentredString x="3 in" y="3.75 in">width=2, dash=5,5</drawCentredString>

        <lineMode width="2" dash="2,10"/>
        <lines>4in 4.5in 5in 4.5in 
        5in 4.5in 4.5in 4in
        4.5in 4in 4.5in 4.75in
        </lines>
        <drawCentredString x="4.5 in" y="3.75 in">width=2, dash=2,10</drawCentredString>

        <lineMode width="2" dash="5,5,2,10"/>
        <lines>5.5in 4.5in 6.5in 4.5in 
        6.5in 4.5in 6in 4in
        6in 4in 6in 4.75in
        </lines>
        <drawCentredString x="6 in" y="3.75 in">width=2, dash=5,5,2,10</drawCentredString>

    </pageGraphics>
    <frame id="first" x1="72" y1="72" width="451" height="698"/> 
    </pageTemplate>
</template>

<stylesheet>
</stylesheet>

<story>
<para></para>
</story>

</document>

Figure 7: Output from EXAMPLE 4