With LaTeX, to natively build a figure, there is the picture
mode. Today, there are also the pstricks
and TikZ
packages.
How was it originally done to draw figures in TeX? Was it possible?
I couldn't find anything about it in the TeXbook.
1 Answer
Disclaimer: some pieces and facts in this answer may be inaccurate (most of the historical facts found around the web), so take it with a grain of salt (corrections welcome).
The DVI format
TeX's DVI format is the simplest possible format to produce typeset output: it knows only about boxes, glue and rules. A character is a box that references a glyph in a font file, possibly separated by the next box by some glue. The glyphs themselves are not known by DVI; it only links them to a font file, and the DVI viewer/printer is responsible for placing the glyphs in the proper boxes (there's a “DVI standard” you might find interesting). There's no space for graphics here, so Knuth added (for this and other purpose) another item to TeX's output: a \special
; this primitive adds some command to the output file directly, and this command ought to be interpreted by the output device (for instance, with \special{pdf:q 1 j 0 1 0 rg 0 0 1 RG 0 0 10 10 re B Q}\bye
(from samplepdf.tex
and running with pdfTeX you get a in the output).
These \specials
require an output device that understands them. The PDF format was only created in 1993, which is recent in terms of TeX history. Before that, we had PostScript created in 1984, a bit later than TeX. However the dvips
program, used to translate TeX's DVI output into PostScript files was only created around 1986 (see this interview with dvips
creator Tomas Rokicki).
Drawing with fonts
Before the creation of dvips
all they had were boxes with font glyphs in them, so that's what was used. Knuth says in Appendix D of The TeXbook:
If you enjoy fooling around making pictures, instead of typesetting ordinary text, TeX will be a source of endless frustration/amusement for you, because almost anything is possible if you have suitable fonts.
(the tikz-pgf tag is here to prove how true that statement is :-)
One example of that is the manfnt
font, used throughout the TeX and METAFONT books for miscellaneous glyphs. For example, if you do:
\font\qc=manfnt
\qc abcd \char127
\bye
you'll get four quarter circles, stored in positions a
, b
, c
and d
of that font, an the famous Dangerous Bend sign:
Knuth also shows some handy macros for those quarter circles so you can make pictures out of them. One of the examples given is the Dragon Curve, which uses carefully placed boxes containing a
, b
, c
, and d
, of the manfnt
:
\font\qc=manfnt
\catcode`\ =9 \endlinechar=-1 % ignore all spaces (temporarily)
\newcount\dir \newdimen\y \newdimen\w
\newif\ifvisible \let\B=\visibletrue \let\W=\visiblefalse
\newbox\NE \newbox\NW \newbox\SE \newbox\SW \newbox\NS \newbox\EW
\setbox\SW=\hbox{\qc a} \setbox\NW=\hbox{\qc b}
\setbox\NE=\hbox{\qc c} \setbox\SE=\hbox{\qc d}
\w=\wd\SW \dimen0=\fontdimen8\qc
\setbox\EW=\hbox{\kern-\dp\SW \vrule height\dimen0 width\wd\SW} \wd\EW=\w
\setbox\NS=\hbox{\vrule height\ht\SW depth\dp\SW width\dimen0} \wd\NS=\w
\def\L{\ifcase\dir \dy+\NW \or\dx-\SW \or\dy-\SE \or\dx+\NE\dd-4\fi \dd+1}
\def\S{\ifcase\dir \dx+\EW \or \dy+\NS \or \dx-\EW \or \dy-\NS \fi}
\def\R{\ifcase\dir \dy-\SW\dd+4 \or\dx+\SE \or\dy+\NE \or\dx-\NW\fi \dd-1}
\def\T{\ifcase\dir\kern-\w\dd+2\or\ey-\dd+2\or\kern\w\dd-2\or\ey+\dd-2\fi}
\edef\dd#1#2{\global\advance\dir#1#2\space}
\def\dx#1#2{\ifvisible\raise\y\copy#2 \if#1-\kern-2\w\fi\else\kern#1\w\fi}
\def\dy#1#2{\ifvisible\raise\y\copy#2 \kern-\w \fi \global\advance\y#1\w}
\def\ey#1{\global\advance\y#1\w}
\def\path#1{\hbox{\B \dir=0 \y=0pt #1}}
\catcode`\ =10 \endlinechar=`\^^M % resume normal spacing conventions
\newcount\n % the current order in the \dragon and \nogard macros
\def\dragon{\ifnum\n>0{\advance\n-1 \dragon\L\nogard}\fi}
\def\nogard{\ifnum\n>0{\advance\n-1 \dragon\R\nogard}\fi}
% end of definitions
\centerline{\path{\dir=3 \n=9 \dragon}}
\bye
which produces:
If you replace manfnt
by, say, cmtt10
you can see that clearly:
This same approach is used by LaTeX (2.09 at the time; the earliest date mentioned in the sources is 1991/08/14, but there's a TUG Boat article by Rainer Schöpf from 1989, so it probably existed for much longer than that), implemented in the picture
environment. The environment has a collection of commands like \put
, \line
, \circle
, etc., which use specially crafted fonts that contain line and circle segments, and places these segments one next to the other to form a picture.
To see these fonts in action you can try:
\documentclass{article}
\begin{document}
{\tenln abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\par}
\end{document}
to see some of the glyphs available (or use the fonttable
package):
The problem with this approach is that you can only have so many different lines in a font file, and as soon as you start to try it out you'll find the limitations. For instance you only have a finite amount of line angles, and anything in between doesn't work (try \put(0,0){\vector(259,966){1}}
), and you also have circles at fixed steps and up to a maximum radius (try \put(0,0){\circle{40}} \put(0,0){\circle{50}}
with the default value of \unitlength
). Take a look at the pict2e
package documentation: it contains some nice comparisons of legacy font-based pictures and “modern” (after PostScript, so 1985 :-) techniques.
Both Knuth's manfnt
and LaTeX's line10
(the font in \tenln
) are made using METAFONT, so in a weird way that was one of the first pieces of software used to add graphics natively (or as close to that as possible) in TeX.
PiCTeX
A rather interesting piece of software developed in the late 80s by Michael Wichura is PiCTeX (TUGboat article). PiCTeX is a macro package that defines its own drawing mechanisms: to draw curves it uses several dots placed one next to the other, overlapping so that at a reading distance it looks like a continuous line.
The package defines its own syntax for drawing things, for example to draw a quarter circle with center at (0,0), from (5,0) to (0,5) you'd use:
\beginpicture
\circulararc 90 degrees from 5 0 center at 0 0
\endpicture
You can replace the manfnt
characters with quarter circles draw with PiCTeX in the Dragon Curve above to get the same curve (code for this at the end of the answer, to avoid clutter). If you zoom in you can see the dots:
You can have fun with \setplotsymbol(<symbol>)
to replace the dot by <symbol>
(\setplotsymbol(?)
gives a nice effect) and \plotsymbolspacing=<distance>
to set the distance between the dots. Mind you that PiCTeX uses a lot of dots, an TeX has to hold all of them in the same page, so you might exhaust its memory quickly (in fact that happened frequently back in the day, for nontrivial pictures). You can find a summary of PiCTeX commands here, and some useful examples here, and a list of sources here. Unfortunately, although PiCTeX is free, its manual is not (you can order a copy here, but I doubt it's useful for more than historical curiosity nowadays).
PostScript
A few years later PostScript, a full-fledged programming language, was developed by Adobe (or Adobe was born from PostScript). Its main intent is to be a page description language, so most of its features align with TeX's DVI, but it has many more features, including drawing and (limited) colour support from the start. Then, in 1986 Tomas Rokicki wrote the dvips
program to convert DVI files into PostScript, so TeX could benefit from that. This allowed for the use of \special
s that would write PostScript code into the page, so with something like:
\special{ps:
50 50 scale
newpath 1 1 moveto
0 1 rlineto 1 0 rlineto
0 -1 rlineto -1 0 rlineto
closepath
gsave 0 1 0 setrgbcolor fill grestore
0 0 1 setrgbcolor
0.05 setlinewidth
stroke}
\bye
and running tex <file>.tex
then dvips <file>.dvi
you'd get a <file>.ps
with a , similar to the PDF command from before.
But bear in mind that TeX still knows absolutely nothing about colour or drawings: it just forwards the \special
to the DVI file, then dvips
picks that up and passes it to the PostScript device to do its thing.
Some time later (around 1993[1,2]) Timothy Van Zandt brought PSTricks (PS stands for PostScript) into the world: a PostScript graphics macro interface for TeX and LaTeX. This macro layer provides commands with key-value interface which eventually translate into PostScript \special
s. The picture from the example above could be rewritten:
\input pstricks
\psframe[fillstyle=solid,linecolor=blue,
fillcolor=green](1,1)
\bye
Around that time, Adobe was developing the PDF format, which was supposed to be a system-independent version of PostScript. It didn't include a programming language, but it also had drawing and colour capabilities. A few years later (1996[1] Hàn Thế Thành wrote pdfTeX: a TeX engine capable of producing PDF files directly, rather having to use dvips
then ps2pdf
. This would allow you to do more or less the same as you did with PostScript, but using PDF commands:
\special{pdf:
q
1 j
0 1 0 rg
0 0 1 RG
0 0 10 10 re
B
Q}
\bye
Into the 21st century and user interfaces
The increasing popularity of computers and computational power several other software appeared to add to the mix. The main ones are XeTeX with an updated output format eXtended DVI (XDV), LuaTeX which uses a similar backend as pdfTeX, but with a few quirks, output to web formats like HTML (using tex4ht
) and SVG (using dvisvgm
). With all these options, basic support packages for graphics and colour adopted a layer of abstraction called a “driver- (or backend-) specific file”. This makes things much easier, because at the macro layer you can say \driver@line{0,0}{10,10}
, then the \driver@line
macro would have the proper definition of (roughly) \special{pdf:0 0 m 10 10 l b}
if the output format is PDF or \special{ps:0 0 moveto 10 10 lineto stroke}
for PostScript or <path d="M 0 0 l 10 10" />
for SVG (just an example, the output for these commands will vary in size and position).
Packages like pict2e
extend LaTeX's picture
environment to produce more or less the same it would with the legacy font-based output, but instead it uses these driver-specific routines, so you can use the package in any engine you like and the driver files will take care of that for you.
From this point on, further abstractions are created on the macro layer to make it easy (terms and conditions may apply) to draw in LaTeX. The biggest example of that is TikZ, which adds an enormous amount of user-friendliness to make \draw (0,0) -- (10,10);
translate eventually to \driver@line{0,0}{10,10}
then \special{pdf:0 0 m 10 10 l b}
. Of course it's not that simple, but the principle remains.
Again, this is not complete nor completely accurate (most of this happened when I was a toddler), but I hope it gives you a sense of how things were back in the day.
Code for PiCTeX Dragon Curve
\input pictex
% \setplotsymbol(?)
% \plotsymbolspacing=1pt
% \plotsymbolspacing=0.01pt % exceeds TeX's memory
\def\pictx#1#2#3#4{%
\beginpicture
\setplotarea x from -5 to 5, y from -5 to 5
\circulararc 90 degrees from #1 #2 center at #3 #4
\endpicture}
\font\qc=manfnt
\catcode`\ =9 \endlinechar=-1 % ignore all spaces (temporarily)
\newcount\dir \newdimen\y \newdimen\w
\newif\ifvisible \let\B=\visibletrue \let\W=\visiblefalse
\newbox\NE \newbox\NW \newbox\SE \newbox\SW \newbox\NS \newbox\EW
\setbox\SW=\hbox{\pictx{-5}{-5}{-10}{-5}}
\setbox\NW=\hbox{\pictx{-10}{0}{-10}{5}}
\setbox\NE=\hbox{\pictx{-5}{5}{0}{5}}
\setbox\SE=\hbox{\pictx{0}{0}{0}{-5}}
\w=\wd\SW \dimen0=\fontdimen8\qc
\setbox\EW=\hbox{\kern-\dp\SW \vrule height\dimen0 width\wd\SW} \wd\EW=\w
\setbox\NS=\hbox{\vrule height\ht\SW depth\dp\SW width\dimen0} \wd\NS=\w
\def\L{\ifcase\dir \dy+\NW \or\dx-\SW \or\dy-\SE \or\dx+\NE\dd-4\fi \dd+1}
\def\S{\ifcase\dir \dx+\EW \or \dy+\NS \or \dx-\EW \or \dy-\NS \fi}
\def\R{\ifcase\dir \dy-\SW\dd+4 \or\dx+\SE \or\dy+\NE \or\dx-\NW\fi \dd-1}
\def\T{\ifcase\dir\kern-\w\dd+2\or\ey-\dd+2\or\kern\w\dd-2\or\ey+\dd-2\fi}
\edef\dd#1#2{\global\advance\dir#1#2\space}
\def\dx#1#2{\ifvisible\raise\y\copy#2 \if#1-\kern-2\w\fi\else\kern#1\w\fi}
\def\dy#1#2{\ifvisible\raise\y\copy#2 \kern-\w \fi \global\advance\y#1\w}
\def\ey#1{\global\advance\y#1\w}
\def\path#1{\hbox{\B \dir=0 \y=0pt #1}}
\catcode`\ =10 \endlinechar=`\^^M % resume normal spacing conventions
\newcount\n % the current order in the \dragon and \nogard macros
\def\dragon{\ifnum\n>0{\advance\n-1 \dragon\L\nogard}\fi}
\def\nogard{\ifnum\n>0{\advance\n-1 \dragon\R\nogard}\fi}
% end of definitions
\centerline{\path{\dir=3 \n=9 \dragon}}
\bye
-
1there were several dvi to ps convertors before dvips, dvitops, dvi2ps, dvipsone, Aug 20, 2020 at 7:35
-
1@AndréC I'm not sure what Michael means with that statement. Maybe he means that you can use a drawing program to generate the PiCTeX code, then PiCTeX does the drawing (in an analogy, think of PGF as similar to PiCTeX: it draws on paper; and think of TikZ as such interface program: you write something like
\draw(0,0)--(1,1);
and it translates to the lower level PGF/PiCTeX command). In this case PiCTeX would behave as the “backend graphics device” (although it's not). I think the Fig-to-PiCTeX program Michael refers to is this one: tug.org/TUGboat/tb11-3/tb29beck.pdf Aug 21, 2020 at 12:22 -
2have you never watched a dot matrix printer do 9 passes per line and 15 minutes or so per page and draw
epic
curves by micro positioned dots..... @AndréC Aug 22, 2020 at 9:35 -
1@AndréC all tex systems of the day had dvi drivers for such printer look at the printers listed in
modes.mf
things likemode_def newdd = %\[ DataDisc (70x93dpi)
so printing on very low resolution printers Aug 22, 2020 at 9:40 -
2
dvi
(device-indepndent) concept applied. So I'd say that it's independent software; its relation to anything else is essentially irrelevant. Hence no need to mention graphics or drawing in the TeXbook.picture
environment that allows you to make drawings. As LaTeX is a set of macros written in TeX, I wonder how people used to make drawings before LaTeX. Did we use Metapost, metafont, pstricks? Did we only make drawings?picture
environment does (try{\tenln abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\par}
in a LaTeX document). Knuth also shows an example of that in appendix D of the TeXBook (search for\dragon
).