Next: , Previous: Page Motions, Up: gtroff Reference


5.23 Drawing Requests

gtroff provides a number of ways to draw lines and other figures on the page. Used in combination with the page motion commands (see Page Motions, for more info), a wide variety of figures can be drawn. However, for complex drawings these operations can be quite cumbersome, and it may be wise to use graphic preprocessors like gpic or ggrn. See gpic, and ggrn, for more information.

All drawing is done via escapes.

— Escape: \l'l'
— Escape: \l'lg'

Draw a line horizontally. l is the length of the line to be drawn. If it is positive, start the line at the current location and draw to the right; its end point is the new current location. Negative values are handled differently: The line starts at the current location and draws to the left, but the current location doesn't move.

l can also be specified absolutely (i.e. with a leading ‘|’) which draws back to the beginning of the input line. Default scaling indicator is ‘m’.

The optional second parameter g is a glyph to draw the line with. If this second argument is not specified, gtroff uses the underscore glyph, \[ru].

To separate the two arguments (to prevent gtroff from interpreting a drawing glyph as a scaling indicator if the glyph is represented by a single character) use \&.

Here a small useful example:

          
          .de box
          \[br]\\$*\[br]\l'|0\[rn]'\l'|0\[ul]'
          ..

Note that this works by outputting a box rule (a vertical line), then the text given as an argument and then another box rule. Finally, the line drawing escapes both draw from the current location to the beginning of the input line – this works because the line length is negative, not moving the current point.

— Escape: \L'l'
— Escape: \L'lg'

Draw vertical lines. Its parameters are similar to the \l escape, except that the default scaling indicator is ‘v’. The movement is downwards for positive values, and upwards for negative values. The default glyph is the box rule glyph, \[br]. As with the vertical motion escapes, text processing blindly continues where the line ends.

          
          This is a \L'3v'test.

Here the result, produced with grotty.

          
          This is a
                    |
                    |
                    |test.
— Escape: \D'command arg ...'

The \D escape provides a variety of drawing functions. Note that on character devices, only vertical and horizontal lines are supported within grotty; other devices may only support a subset of the available drawing functions.

The default scaling indicator for all subcommands of \D is ‘m’ for horizontal distances and ‘v’ for vertical ones. Exceptions are \D'f ...' and \D't ...' which use u as the default, and \D'Fx ...' which arguments are treated similar to the defcolor request.

\D'l dx dy'
Draw a line from the current location to the relative point specified by (dx,dy), where positive values mean down and right, respectively. The end point of the line is the new current location.

The following example is a macro for creating a box around a text string; for simplicity, the box margin is taken as a fixed value, 0.2m.

               
               .de BOX
               .  nr @wd \w'\\$1'
               \h'.2m'\
               \h'-.2m'\v'(.2m - \\n[rsb]u)'\
               \D'l 0 -(\\n[rst]u - \\n[rsb]u + .4m)'\
               \D'l (\\n[@wd]u + .4m) 0'\
               \D'l 0 (\\n[rst]u - \\n[rsb]u + .4m)'\
               \D'l -(\\n[@wd]u + .4m) 0'\
               \h'.2m'\v'-(.2m - \\n[rsb]u)'\
               \\$1\
               \h'.2m'
               ..

First, the width of the string is stored in register @wd. Then, four lines are drawn to form a box, properly offset by the box margin. The registers rst and rsb are set by the \w escape, containing the largest height and depth of the whole string.

\D'c d'
Draw a circle with a diameter of d with the leftmost point at the current position. After drawing, the current location is positioned at the rightmost point of the circle.
\D'C d'
Draw a solid circle with the same parameters and behaviour as an outlined circle. No outline is drawn.
\D'e x y'
Draw an ellipse with a horizontal diameter of x and a vertical diameter of y with the leftmost point at the current position. After drawing, the current location is positioned at the rightmost point of the ellipse.
\D'E x y'
Draw a solid ellipse with the same parameters and behaviour as an outlined ellipse. No outline is drawn.
\D'a dx1 dy1 dx2 dy2'
Draw an arc clockwise from the current location through the two specified relative locations (dx1,dy1) and (dx2,dy2). The coordinates of the first point are relative to the current position, and the coordinates of the second point are relative to the first point. After drawing, the current position is moved to the final point of the arc.
\D'~ dx1 dy1 dx2 dy2 ...'
Draw a spline from the current location to the relative point (dx1,dy1) and then to (dx2,dy2), and so on. The current position is moved to the terminal point of the drawn curve.
\D'f n'
Set the shade of gray to be used for filling solid objects to n; n must be an integer between 0 and 1000, where 0 corresponds solid white and 1000 to solid black, and values in between correspond to intermediate shades of gray. This applies only to solid circles, solid ellipses, and solid polygons. By default, a level of 1000 is used.

Despite of being silly, the current point is moved horizontally to the right by n.

Don't use this command! It has the serious drawback that it is always rounded to the next integer multiple of the horizontal resolution (the value of the hor keyword in the DESC file). Use \M (see Colors) or \D'Fg ...' instead.

\D'p dx1 dy1 dx2 dy2 ...'
Draw a polygon from the current location to the relative position (dx1,dy1) and then to (dx2,dy2) and so on. When the specified data points are exhausted, a line is drawn back to the starting point. The current position is changed by adding the sum of all arguments with odd index to the actual horizontal position and the even ones to the vertical position.
\D'P dx1 dy1 dx2 dy2 ...'
Draw a solid polygon with the same parameters and behaviour as an outlined polygon. No outline is drawn.

Here a better variant of the box macro to fill the box with some color. Note that the box must be drawn before the text since colors in gtroff are not transparent; the filled polygon would hide the text completely.

               
               .de BOX
               .  nr @wd \w'\\$1'
               \h'.2m'\
               \h'-.2m'\v'(.2m - \\n[rsb]u)'\
               \M[lightcyan]\
               \D'P 0 -(\\n[rst]u - \\n[rsb]u + .4m) \
                    (\\n[@wd]u + .4m) 0 \
                    0 (\\n[rst]u - \\n[rsb]u + .4m) \
                    -(\\n[@wd]u + .4m) 0'\
               \h'.2m'\v'-(.2m - \\n[rsb]u)'\
               \M[]\
               \\$1\
               \h'.2m'
               ..

If you want a filled polygon which has exactly the same size as an unfilled one, you must draw both an unfilled and a filled polygon. A filled polygon is always smaller than an unfilled one because the latter uses straight lines with a given line thickness to connect the polygon's corners, while the former simply fills the area defined by the coordinates.

               
               \h'1i'\v'1i'\
               \# increase line thickness
               \Z'\D't 5p''\
               \# draw unfilled polygon
               \Z'\D'p 3 3 -6 0''\
               \# draw filled polygon
               \Z'\D'P 3 3 -6 0''

\D't n'
Set the current line thickness to n machine units. A value of zero selects the smallest available line thickness. A negative value makes the line thickness proportional to the current point size (this is the default behaviour of AT&T troff).

Despite of being silly, the current point is moved horizontally to the right by n.

\D'Fscheme color_components'
Change current fill color. scheme is a single letter denoting the color scheme: ‘r’ (rgb), ‘c’ (cmy), ‘k’ (cmyk), ‘g’ (gray), or ‘d’ (default color). The color components use exactly the same syntax as in the defcolor request (see Colors); the command \D'Fd' doesn't take an argument.

No position changing!

Examples:


          

\D'Fg .3' \" same gray as \D'f 700' \D'Fr #0000ff' \" blue

See Graphics Commands.

— Escape: \b'string'

Pile a sequence of glyphs vertically, and center it vertically on the current line. Use it to build large brackets and braces.

Here an example how to create a large opening brace:

          
          \b'\[lt]\[bv]\[lk]\[bv]\[lb]'

The first glyph is on the top, the last glyph in string is at the bottom. Note that gtroff separates the glyphs vertically by 1m, and the whole object is centered 0.5m above the current baseline; the largest glyph width is used as the width for the whole object. This rather unflexible positioning algorithm doesn't work with -Tdvi since the bracket pieces vary in height for this device. Instead, use the eqn preprocessor.

See Manipulating Spacing, how to adjust the vertical spacing with the \x escape.