groff: Drawing Requests
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'.
⇒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 is 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 right and
down, 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' (⇒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 that 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 (⇒
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
⇒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.
⇒Manipulating Spacing, how to adjust the vertical spacing
with the '\x' escape.