18

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.

18
  • no idea, I don't use plain. But some of the packages on ctan mention plain tex. – Ulrike Fischer Aug 13 '20 at 20:11
  • Your answer comforts me, I'm not the only one who doesn't know. I wonder because TikZ is written in TeX (it seems) since it can be used in Plain TeX. And so there are TeX primitives (or macros) that can be used to make drawings. How it works, it's a real problem since it seems to me that Donald Knuth himself used another language (Metafont) to make drawings... – AndréC Aug 13 '20 at 20:17
  • sorry I don't really get your problem. Naturally is tikz written in tex, what else? And it also works in plain. And there are various packages for drawing which also works in plain, including metafont and metapost based. I only have no idea which a normal plain tex would use. – Ulrike Fischer Aug 13 '20 at 20:22
  • 1
    tikz is not completly written in tex. it uses postscript when used with dvips, see e.g. pgfsys-common-postscript.def. And the other backends have special commands too. – Ulrike Fischer Aug 13 '20 at 20:38
  • 1
    Not entirely true. The person I was drawing the plots for had a little analog device that would draw rough images based on the data, which he used to make sure I was getting the correct (quite refined) images. (I was hired on the basis of a recommendation by my Girl Scout leader, who was a graduate student in the department.) He only fessed up after I had delivered good work, and on that basis, I was hired again for the second summer. There were computer programs for engineering and architectural work, but they were expensive, and the plotting tables took a lot of space. – barbara beeton Aug 14 '20 at 21:22
36
+200

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 enter image description here 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 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:

enter image description here

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:

enter image description here

If you replace manfnt by, say, cmtt10 you can see that clearly:

enter image description here

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):

enter image description here

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:

enter image description here

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 \specials 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 enter image description here, 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 \specials. The picture from the example above could be rewritten:

\input pstricks
\psframe[fillstyle=solid,linecolor=blue,
  fillcolor=green](1,1)
\bye

PDF

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
19
  • 1
    there were several dvi to ps convertors before dvips, dvitops, dvi2ps, dvipsone, – David Carlisle Aug 20 '20 at 7:35
  • 1
    have 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 – David Carlisle Aug 22 '20 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 like mode_def newdd = %\[ DataDisc (70x93dpi) so printing on very low resolution printers – David Carlisle Aug 22 '20 at 9:40
  • 1
    @AndréC eg 4tex.ntg.nl/4tex4/4texdoc/4tse40.htm – David Carlisle Aug 22 '20 at 10:07
  • 1
    And then there was MetaPost, which is now embedded in LuaTeX as a library. And of course we have tikz/pgf. – Martin Schröder Sep 1 '20 at 7:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.