ken@rochester.UUCP (Ken Yap) (04/21/88)
comp.sources.misc: Volume 2, Issue 101 Submitted-By: "Ken Yap" <ken@rochester.UUCP> Archive-Name: ditdvi I'm sick of this kid. Out the door it goes. Ken #!/bin/sh # This is a shell archive, meaning: # 1. Remove everything above the #!/bin/sh line. # 2. Save the resulting text in a file. # 3. Execute the file with /bin/sh (not csh) to create the files: # README # Makefile # cmbx10 # cmmi10 # cmr10 # cmss10 # cmssbx10 # cmssi10 # cmsy10 # cmti10 # cmtt10 # ditdvi.1 # ditdvi.c # ditdvi.h # dvi.c # dvi.h # fontfile.c # getspecials # reader.c # tfm2desc.1 # tfm2desc.c # This archive created: Tue Apr 19 19:06:41 1988 # By: Ken Yap () export PATH; PATH=/bin:$PATH echo shar: extracting "'README'" '(4022 characters)' if test -f 'README' then echo shar: over-writing existing file "'README'" fi cat << \SHAR_EOF > 'README' These are the sources for a ditroff (not troff) to TeX DVI converter. I wrote this on a lark and to learn DVI format. Some reasons why you may want this: + Your high resolution printer accepts DVI but you don't have a ditroff filter for it. + You want to access the wide range of characters in TeX fonts. + You want to create weird and wonderful fonts for ditroff with METAFONT. + You have only a DVI previewer. + You want to standardize on one type of output. + You want to give the operator of a non-Unix machine a fit by printing a Unix man page on the DVI printer. + (Put your own reason here.) It works pretty well and I have printed tens of pages of documentation with it. You may do whatever you like with the source, except make money out of it (because I gave it to you for free to begin with). Do leave my name in this documentation. How it works: Edit Makefile to specify where the TeX tfm files live and where ditroff expects to find the binary tables. The files cm* define the fonts of a virtual printer called dvi. You run the program tfm2desc to generate font tables in the files R, I, B, etc. See the man page for tfm2desc and the Makefile entry for metrics for flags to tfm2desc. Make all, then run makedev (in your ditroff distribution, not supplied here) or a PD version of that to make binary font tables for ditroff. Install these binary tables in a subdirectory called devdvi near where ditroff expects to find other tables. If you want to add fonts, make up more cm* description files and edit Makefile to add the font names. You have to estimate the spacewidth passed to tfm2desc. I use half of the width of a digit. cmss isn't really Helvetica, just sort of sans serif. The resolution of this virtual printer is irrelevant so I've set it at 576 (8*72). You can change this in the Makefile. You must choose a unitwidth such that all the character widths are under 256, because ditroff stores the widths in single bytes. The roundoff error will be minimized if the widths are as large as possible. Fortunately for ditroff, the resolution of DVI files is much higher than anything ditroff can comprehend. (1 / 2^16 of a point, if you are curious.) Sizes 10 and below are translated to TeX fonts at their respective design size. Above that, magnification is used. Hence the code to translate size to magnification in reader.c. Most TeX fonts follow this pattern of availability. Unfortunately the SIZES macro in the Makefile isn't all you have to change if you want to add more sizes. You also have to edit the switch statement in reader.c and make sure you have the fonts in the right design size and magnification. Note that if you don't have a font of the right size, you don't find out until you try to print the DVI file, or convert it to your printer language. There is no room for the spaces or rule characters in the TeX character set, so I've put spaces at 0200 and the rule at 0201. The constant 0201 is hacked into tfm2desc and ditdvi. Sorry. I haven't tried out how well extended parens, brackets and braces are drawn with eqn. Drawing functions are not implemented. You can translate these to tpic generated \specials. I'm too lazy. Some special characters must be provided to ditroff or it will have a fit or at least drop your characters silently. These include hyphen (hy), mathtimes (**), vertical bar (bv), the spaces and rule. The whole sordid story can be read in "Adventures with Typesetter Independent Troff" by Moore and Kahrs, TR 159, June 1985, Computer Science Dept., U. of Rochester. It's fascinating how much knowledge of the special fonts is still hardwired into ditroff. There is one potential bug in fontfile.c. A pointer to a table of shorts may be non-word aligned. Some machines don't like this. You need to do a block copy to malloc'ed memory. Again, I was lazy. If you have old troff, my condolences. Have fun. You can send me bug reports but I'm not too motivated to do much about them. Ken Yap ken@cs.rochester.edu April 1988 SHAR_EOF if test 4022 -ne "`wc -c 'README'`" then echo shar: error transmitting "'README'" '(should have been 4022 characters)' fi echo shar: extracting "'Makefile'" '(1609 characters)' if test -f 'Makefile' then echo shar: over-writing existing file "'Makefile'" fi cat << \SHAR_EOF > 'Makefile' CFLAGS = -g -DRESOLUTION=$(RESOLUTION) -DFONTDIR=\"$(FONTDIR)\" -DTEXFONT=\"$(TEXFONT)\" RESOLUTION = 576 UNITWIDTH = 24 FONTS = R I B H HB HI C M S SIZES = 5 6 7 8 9 10 11 12 14 17 24 25 0 FONTDIR = /u/ken/lib/ditdvi TEXFONT = /usr/lib/tex/fonts/ all: tfm2desc ditdvi metrics descfile ditdvi: ditdvi.o reader.o dvi.o fontfile.o $(CC) $(LDFLAGS) $(CFLAGS) -o $@ ditdvi.o reader.o dvi.o fontfile.o ditdvi.o: ditdvi.c ditdvi.h reader.o: reader.c ditdvi.h dvi.o: dvi.c dvi.h fontfile.o: fontfile.c ditdvi.h tfm2desc.o: tfm2desc.c tfm2desc: tfm2desc.o $(CC) $(LDFLAGS) $(CFLAGS) -o $@ tfm2desc.o metrics: tfm2desc tfm2desc -d$(UNITWIDTH) -s48 cmr10 > R tfm2desc -d$(UNITWIDTH) -s55 cmbx10 > B tfm2desc -d$(UNITWIDTH) -s49 cmti10 > I tfm2desc -d$(UNITWIDTH) -s48 cmss10 > H tfm2desc -d$(UNITWIDTH) -s53 cmssbx10 > HB tfm2desc -d$(UNITWIDTH) -s49 cmssi10 > HI tfm2desc -d$(UNITWIDTH) -s101 cmtt10 m > C tfm2desc -d$(UNITWIDTH) -s48 cmmi10 s > M tfm2desc -d$(UNITWIDTH) -s48 cmsy10 s > S # # mc is a local program that does multicolumn # you can figure out something with awk, I'm sure # descfile: echo '# ditroff device description for TeX' > DESC echo fonts `echo $(FONTS) | wc -w` $(FONTS) >> DESC echo sizes $(SIZES) >> DESC echo res $(RESOLUTION) >> DESC echo hor 1 >> DESC echo vert 1 >> DESC echo unitwidth $(UNITWIDTH) >> DESC echo paperwidth `expr $(RESOLUTION) \* 17 / 2` >> DESC echo paperlength `expr $(RESOLUTION) \* 11` >> DESC echo charset >> DESC getspecials | mc >> DESC backup: cd ..; ctar Ditdvi | rsh can 'cd Src/Text/TeX; vtar' SHAR_EOF if test 1609 -ne "`wc -c 'Makefile'`" then echo shar: error transmitting "'Makefile'" '(should have been 1609 characters)' fi echo shar: extracting "'cmbx10'" '(874 characters)' if test -f 'cmbx10' then echo shar: over-writing existing file "'cmbx10'" fi cat << \SHAR_EOF > 'cmbx10' B 000 *G 001 *D 002 *H 003 *L 004 *C 005 *P 006 *S 007 *U 010 *F 011 *Q 012 *W 013 ff 014 fi 015 fl 016 Fi 017 Fl 020 ui 021 uj 022 \` 022 ga 023 \' 023 aa 024 hc 025 be 026 ma 027 ri 030 cd 031 ss 032 ae 033 oe 034 o/ 035 AE 036 OE 037 O/ 041 ! 042 " 042 rq 043 # 044 $ 045 % 046 & 047 ' 050 ( 051 ) 052 * 053 + 054 , 055 - 055 \- 055 hy 056 . 057 / 060 0 061 1 062 2 063 3 064 4 065 5 066 6 067 7 070 8 071 9 072 : 073 ; 074 !! 074 I! 075 = 076 I? 077 ? 100 @ 101 A 102 B 103 C 104 D 105 E 106 F 107 G 110 H 111 I 112 J 113 K 114 L 115 M 116 N 117 O 120 P 121 Q 122 R 123 S 124 T 125 U 126 V 127 W 130 X 131 Y 132 Z 133 [ 134 lq 135 ] 136 ^ 137 dt 140 ` 141 a 142 b 143 c 144 d 145 e 146 f 147 g 150 h 151 i 152 j 153 k 154 l 155 m 156 n 157 o 160 p 161 q 162 r 163 s 164 t 165 u 166 v 167 w 170 x 171 y 172 z 173 en 174 em 175 '' 176 ~ 177 .. 177 um 200 \& 200 \| 200 \^ SHAR_EOF if test 874 -ne "`wc -c 'cmbx10'`" then echo shar: error transmitting "'cmbx10'" '(should have been 874 characters)' fi echo shar: extracting "'cmmi10'" '(766 characters)' if test -f 'cmmi10' then echo shar: over-writing existing file "'cmmi10'" fi cat << \SHAR_EOF > 'cmmi10' M 000 *G 001 *D 002 *H 003 *L 004 *C 005 *P 006 *S 007 *U 010 *F 011 *Q 012 *W 013 *a 014 *b 015 *g 016 *d 017 *e 020 *z 021 *y 022 *h 023 *i 024 *k 025 *l 026 *m 027 *n 030 *c 031 *p 032 *r 033 *s 034 *t 035 *u 036 *f 037 *x 040 *q 041 *w 042 Ve 043 Vh 044 Vp 045 Vr 046 ts 047 Vf 060 0 061 1 062 2 063 3 064 4 065 5 066 6 067 7 070 8 071 9 072 . 073 , 074 < 075 / 076 > 077 * 100 pd 101 A 102 B 103 C 104 D 105 E 106 F 107 G 110 H 111 I 112 J 113 K 114 L 115 M 116 N 117 O 120 P 121 Q 122 R 123 S 124 T 125 U 126 V 127 W 130 X 131 Y 132 Z 140 li 141 a 142 b 143 c 144 d 145 e 146 f 147 g 150 h 151 i 152 j 153 k 154 l 155 m 156 n 157 o 160 p 161 q 162 r 163 s 164 t 165 u 166 v 167 w 170 x 171 y 172 z 173 ui 174 uj 177 cp 200 \& 200 \| 200 \^ 201 ru 201 _ 201 \_ SHAR_EOF if test 766 -ne "`wc -c 'cmmi10'`" then echo shar: error transmitting "'cmmi10'" '(should have been 766 characters)' fi echo shar: extracting "'cmr10'" '(874 characters)' if test -f 'cmr10' then echo shar: over-writing existing file "'cmr10'" fi cat << \SHAR_EOF > 'cmr10' R 000 *G 001 *D 002 *H 003 *L 004 *C 005 *P 006 *S 007 *U 010 *F 011 *Q 012 *W 013 ff 014 fi 015 fl 016 Fi 017 Fl 020 ui 021 uj 022 \` 022 ga 023 \' 023 aa 024 hc 025 be 026 ma 027 ri 030 cd 031 ss 032 ae 033 oe 034 o/ 035 AE 036 OE 037 O/ 041 ! 042 " 042 rq 043 # 044 $ 045 % 046 & 047 ' 050 ( 051 ) 052 * 053 + 054 , 055 - 055 \- 055 hy 056 . 057 / 060 0 061 1 062 2 063 3 064 4 065 5 066 6 067 7 070 8 071 9 072 : 073 ; 074 !! 074 I! 075 = 076 I? 077 ? 100 @ 101 A 102 B 103 C 104 D 105 E 106 F 107 G 110 H 111 I 112 J 113 K 114 L 115 M 116 N 117 O 120 P 121 Q 122 R 123 S 124 T 125 U 126 V 127 W 130 X 131 Y 132 Z 133 [ 134 lq 135 ] 136 ^ 137 dt 140 ` 141 a 142 b 143 c 144 d 145 e 146 f 147 g 150 h 151 i 152 j 153 k 154 l 155 m 156 n 157 o 160 p 161 q 162 r 163 s 164 t 165 u 166 v 167 w 170 x 171 y 172 z 173 en 174 em 175 '' 176 ~ 177 .. 177 um 200 \& 200 \| 200 \^ SHAR_EOF if test 874 -ne "`wc -c 'cmr10'`" then echo shar: error transmitting "'cmr10'" '(should have been 874 characters)' fi echo shar: extracting "'cmss10'" '(874 characters)' if test -f 'cmss10' then echo shar: over-writing existing file "'cmss10'" fi cat << \SHAR_EOF > 'cmss10' H 000 *G 001 *D 002 *H 003 *L 004 *C 005 *P 006 *S 007 *U 010 *F 011 *Q 012 *W 013 ff 014 fi 015 fl 016 Fi 017 Fl 020 ui 021 uj 022 \` 022 ga 023 \' 023 aa 024 hc 025 be 026 ma 027 ri 030 cd 031 ss 032 ae 033 oe 034 o/ 035 AE 036 OE 037 O/ 041 ! 042 " 042 rq 043 # 044 $ 045 % 046 & 047 ' 050 ( 051 ) 052 * 053 + 054 , 055 - 055 \- 055 hy 056 . 057 / 060 0 061 1 062 2 063 3 064 4 065 5 066 6 067 7 070 8 071 9 072 : 073 ; 074 !! 074 I! 075 = 076 I? 077 ? 100 @ 101 A 102 B 103 C 104 D 105 E 106 F 107 G 110 H 111 I 112 J 113 K 114 L 115 M 116 N 117 O 120 P 121 Q 122 R 123 S 124 T 125 U 126 V 127 W 130 X 131 Y 132 Z 133 [ 134 lq 135 ] 136 ^ 137 dt 140 ` 141 a 142 b 143 c 144 d 145 e 146 f 147 g 150 h 151 i 152 j 153 k 154 l 155 m 156 n 157 o 160 p 161 q 162 r 163 s 164 t 165 u 166 v 167 w 170 x 171 y 172 z 173 en 174 em 175 '' 176 ~ 177 .. 177 um 200 \& 200 \| 200 \^ SHAR_EOF if test 874 -ne "`wc -c 'cmss10'`" then echo shar: error transmitting "'cmss10'" '(should have been 874 characters)' fi echo shar: extracting "'cmssbx10'" '(875 characters)' if test -f 'cmssbx10' then echo shar: over-writing existing file "'cmssbx10'" fi cat << \SHAR_EOF > 'cmssbx10' HB 000 *G 001 *D 002 *H 003 *L 004 *C 005 *P 006 *S 007 *U 010 *F 011 *Q 012 *W 013 ff 014 fi 015 fl 016 Fi 017 Fl 020 ui 021 uj 022 \` 022 ga 023 \' 023 aa 024 hc 025 be 026 ma 027 ri 030 cd 031 ss 032 ae 033 oe 034 o/ 035 AE 036 OE 037 O/ 041 ! 042 " 042 rq 043 # 044 $ 045 % 046 & 047 ' 050 ( 051 ) 052 * 053 + 054 , 055 - 055 \- 055 hy 056 . 057 / 060 0 061 1 062 2 063 3 064 4 065 5 066 6 067 7 070 8 071 9 072 : 073 ; 074 !! 074 I! 075 = 076 I? 077 ? 100 @ 101 A 102 B 103 C 104 D 105 E 106 F 107 G 110 H 111 I 112 J 113 K 114 L 115 M 116 N 117 O 120 P 121 Q 122 R 123 S 124 T 125 U 126 V 127 W 130 X 131 Y 132 Z 133 [ 134 lq 135 ] 136 ^ 137 dt 140 ` 141 a 142 b 143 c 144 d 145 e 146 f 147 g 150 h 151 i 152 j 153 k 154 l 155 m 156 n 157 o 160 p 161 q 162 r 163 s 164 t 165 u 166 v 167 w 170 x 171 y 172 z 173 en 174 em 175 '' 176 ~ 177 .. 177 um 200 \& 200 \| 200 \^ SHAR_EOF if test 875 -ne "`wc -c 'cmssbx10'`" then echo shar: error transmitting "'cmssbx10'" '(should have been 875 characters)' fi echo shar: extracting "'cmssi10'" '(897 characters)' if test -f 'cmssi10' then echo shar: over-writing existing file "'cmssi10'" fi cat << \SHAR_EOF > 'cmssi10' HI 000 *G 001 *D 002 *H 003 *L 004 *C 005 *P 006 *S 007 *U 010 *F 011 *Q 012 *W 013 ff 014 fi 015 fl 016 Fi 017 Fl 020 ui 021 uj 022 \` 022 ga 023 \' 023 aa 024 hc 025 be 026 ma 027 ri 030 cd 031 ss 032 ae 033 oe 034 o/ 035 AE 036 OE 037 O/ 041 ! 042 " 042 rq 043 # 044 po 044 ps 045 % 046 & 047 ' 050 ( 051 ) 052 * 053 + 053 pl 054 , 055 - 055 \- 055 hy 056 . 057 / 060 0 061 1 062 2 063 3 064 4 065 5 066 6 067 7 070 8 071 9 072 : 073 ; 074 !! 074 I! 075 = 075 eq 076 I? 077 ? 100 @ 101 A 102 B 103 C 104 D 105 E 106 F 107 G 110 H 111 I 112 J 113 K 114 L 115 M 116 N 117 O 120 P 121 Q 122 R 123 S 124 T 125 U 126 V 127 W 130 X 131 Y 132 Z 133 [ 134 lq 135 ] 136 ^ 137 dt 140 ` 141 a 142 b 143 c 144 d 145 e 146 f 147 g 150 h 151 i 152 j 153 k 154 l 155 m 156 n 157 o 160 p 161 q 162 r 163 s 164 t 165 u 166 v 167 w 170 x 171 y 172 z 173 en 174 em 175 '' 176 ~ 177 .. 177 um 200 \& 200 \| 200 \^ SHAR_EOF if test 897 -ne "`wc -c 'cmssi10'`" then echo shar: error transmitting "'cmssi10'" '(should have been 897 characters)' fi echo shar: extracting "'cmsy10'" '(809 characters)' if test -f 'cmsy10' then echo shar: over-writing existing file "'cmsy10'" fi cat << \SHAR_EOF > 'cmsy10' S 000 mi 001 m. 002 mu 003 ** 004 di 005 dm 006 +- 007 -+ 010 a+ 011 a- 012 ax 013 a/ 015 ci 016 mc 017 bu 021 == 022 ib 023 ip 024 <= 025 >= 030 ap 031 ~~ 032 sb 033 sp 034 << 035 >> 036 l< 037 r> 040 <- 041 -> 042 ua 043 da 044 <> 045 NE 046 SE 047 ~= 050 <: 051 :> 051 im 055 NW 056 SW 057 pt 061 if 062 mo 063 cm 064 tr 066 sl 070 fa 071 te 072 no 073 es 074 R# 075 I# 076 to 077 bt 100 al 101 A 102 B 103 C 104 D 105 E 106 F 107 G 110 H 111 I 112 J 113 K 114 L 115 M 116 N 117 O 120 P 121 Q 122 R 123 S 124 T 125 U 126 V 127 W 130 X 131 Y 132 X 133 cu 134 ca 136 an 137 \/ 137 lo 140 |- 140 st 141 -| 142 lf 143 rf 144 lc 145 rc 146 { 147 } 150 < 151 > 152 | 152 or 152 bv 153 || 156 \ 160 sr 162 gr 163 is 170 sc 171 dg 172 dd 173 pp 174 cS 175 dS 176 hS 177 sS 200 \& 200 \| 200 \^ 201 ru 201 _ 201 \_ SHAR_EOF if test 809 -ne "`wc -c 'cmsy10'`" then echo shar: error transmitting "'cmsy10'" '(should have been 809 characters)' fi echo shar: extracting "'cmti10'" '(896 characters)' if test -f 'cmti10' then echo shar: over-writing existing file "'cmti10'" fi cat << \SHAR_EOF > 'cmti10' I 000 *G 001 *D 002 *H 003 *L 004 *C 005 *P 006 *S 007 *U 010 *F 011 *Q 012 *W 013 ff 014 fi 015 fl 016 Fi 017 Fl 020 ui 021 uj 022 \` 022 ga 023 \' 023 aa 024 hc 025 be 026 ma 027 ri 030 cd 031 ss 032 ae 033 oe 034 o/ 035 AE 036 OE 037 O/ 041 ! 042 " 042 rq 043 # 044 po 044 ps 045 % 046 & 047 ' 050 ( 051 ) 052 * 053 + 053 pl 054 , 055 - 055 \- 055 hy 056 . 057 / 060 0 061 1 062 2 063 3 064 4 065 5 066 6 067 7 070 8 071 9 072 : 073 ; 074 !! 074 I! 075 = 075 eq 076 I? 077 ? 100 @ 101 A 102 B 103 C 104 D 105 E 106 F 107 G 110 H 111 I 112 J 113 K 114 L 115 M 116 N 117 O 120 P 121 Q 122 R 123 S 124 T 125 U 126 V 127 W 130 X 131 Y 132 Z 133 [ 134 lq 135 ] 136 ^ 137 dt 140 ` 141 a 142 b 143 c 144 d 145 e 146 f 147 g 150 h 151 i 152 j 153 k 154 l 155 m 156 n 157 o 160 p 161 q 162 r 163 s 164 t 165 u 166 v 167 w 170 x 171 y 172 z 173 en 174 em 175 '' 176 ~ 177 .. 177 um 200 \& 200 \| 200 \^ SHAR_EOF if test 896 -ne "`wc -c 'cmti10'`" then echo shar: error transmitting "'cmti10'" '(should have been 896 characters)' fi echo shar: extracting "'cmtt10'" '(860 characters)' if test -f 'cmtt10' then echo shar: over-writing existing file "'cmtt10'" fi cat << \SHAR_EOF > 'cmtt10' C 000 *G 001 *D 002 *H 003 *L 004 *C 005 *P 006 *S 007 *U 010 *F 011 *Q 012 *W 013 ua 014 da 015 n' 016 !! 016 I! 017 I? 020 ui 021 uj 022 \` 022 ga 023 \' 023 aa 024 hc 025 be 026 ma 027 ri 030 cd 031 ss 032 ae 033 oe 034 o/ 035 AE 036 OE 037 O/ 040 __ 041 ! 042 " 043 # 044 $ 045 % 046 & 047 ' 050 ( 051 ) 052 * 053 + 054 , 055 - 055 \- 056 . 057 / 060 0 061 1 062 2 063 3 064 4 065 5 066 6 067 7 070 8 071 9 072 : 073 ; 074 < 075 = 076 > 077 ? 100 @ 101 A 102 B 103 C 104 D 105 E 106 F 107 G 110 H 111 I 112 J 113 K 114 L 115 M 116 N 117 O 120 P 121 Q 122 R 123 S 124 T 125 U 126 V 127 W 130 X 131 Y 132 Z 133 [ 134 \ 135 ] 136 ^ 137 _ 140 ` 141 a 142 b 143 c 144 d 145 e 146 f 147 g 150 h 151 i 152 j 153 k 154 l 155 m 156 n 157 o 160 p 161 q 162 r 163 s 164 t 165 u 166 v 167 w 170 x 171 y 172 z 173 { 174 | 175 } 176 ~ 177 .. 177 um 200 \& 200 \| 200 \^ SHAR_EOF if test 860 -ne "`wc -c 'cmtt10'`" then echo shar: error transmitting "'cmtt10'" '(should have been 860 characters)' fi echo shar: extracting "'ditdvi.1'" '(636 characters)' if test -f 'ditdvi.1' then echo shar: over-writing existing file "'ditdvi.1'" fi cat << \SHAR_EOF > 'ditdvi.1' .TH DITDVI 1 4/9/88 .CM 1 .SH "NAME" ditdvi \- convert ditroff output to DVI .SH "SYNOPSIS" ditdvi [\fB\-o\fP] < file.di > file.dvi .SH "DESCRIPTION" \fIDitdvi\fP converts ditroff(1) output to DVI output. The ditroff output should have been generated for a virtual DVI printer. .PP The \fB\-o\fP flag turns on the standard 1 inch top and left margins for the output. This option is for previewing the DVI output with DVI previewers that crop margins. .SH "FILES" FONTDIR where the DESC file for the virtual printer lives .SH "SEE ALSO" ditroff(1), makedev(1), tfm2desc(1) .SH "DIAGNOSTICS" Hopefully self-explanatory. .SH "BUGS" Lots. SHAR_EOF if test 636 -ne "`wc -c 'ditdvi.1'`" then echo shar: error transmitting "'ditdvi.1'" '(should have been 636 characters)' fi echo shar: extracting "'ditdvi.c'" '(646 characters)' if test -f 'ditdvi.c' then echo shar: over-writing existing file "'ditdvi.c'" fi cat << \SHAR_EOF > 'ditdvi.c' #include <stdio.h> #include "ditdvi.h" char pageoffset = 1; char *prog_name; /*VARARGS1*/ fatal(s, arg1, arg2) char *s; int arg1, arg2; { (void)fprintf(stderr, s, arg1, arg2); exit(1); } main(argc, argv) int argc; char *argv[]; { register int c; char *rindex(); int getopt(); extern int optind; extern char *optarg; if ((prog_name = rindex(argv[0], '/')) == NULL) prog_name = argv[0]; else ++prog_name; while ((c = getopt(argc, argv, "o")) != EOF) { switch (c) { case 'o': pageoffset = 0; break; default: fatal("Usage: %s [-o] < f.di > f.dvi\n", prog_name); break; } } reader(); exit(0); } SHAR_EOF if test 646 -ne "`wc -c 'ditdvi.c'`" then echo shar: error transmitting "'ditdvi.c'" '(should have been 646 characters)' fi echo shar: extracting "'ditdvi.h'" '(2724 characters)' if test -f 'ditdvi.h' then echo shar: over-writing existing file "'ditdvi.h'" fi cat << \SHAR_EOF > 'ditdvi.h' #ifndef FONTDIR #define FONTDIR "/usr/lib/ditroff" #endif #define DEF_DEV "dvi" #define NFONTS 100 #define NSIZES 20 #define RULE_CHAR 0201 /* put here by tfm2desc */ char *strcpy(), *sprintf(); typedef unsigned char uchar; extern char pageoffset; extern char *prog_name; /* ** characteristics of a typesetter */ typedef struct tdev { unsigned short filesize; /* number of bytes in file, */ /* excluding dev part */ short res; /* basic resolution in goobies/inch */ short hor; /* goobies horizontally */ short vert; short unitwidth; /* size at which widths are given, in effect */ short nfonts; /* number of fonts physically available */ short nsizes; /* number of sizes it has */ short sizescale; /* scaling for fractional point sizes */ short paperwidth; /* max line length in units */ short paperlength; /* max paper length in units */ short nchtab; /* number of funny names in chtab */ short lchname; /* length of chname table */ short spare1; /* in case of expansion */ short spare2; } tdev; typedef struct tfont { /* characteristics of a font */ uchar nwfont; /* number of width entries for this font */ char specfont; /* 1 == special font */ char ligfont; /* 1 == ligatures exist on this font */ char spare1; /* unused for now */ char namefont[10]; /* name of this font (e.g., "R" */ char intname[10]; /* internal name on device, in ascii */ } tfont; /* ligatures, ORed into ligfont */ #define LFF 01 #define LFI 02 #define LFL 04 #define LFFI 010 #define LFFL 020 typedef struct lookup { char *chname; short ordinal; } lookup; typedef struct settings { char s_ts_name[20]; /* name of typesetter */ char *s_font_name; /* current font name */ int s_font_num; /* current font number */ int s_point_size; /* current point size */ int s_point_index; /* index into pstab and raster */ int s_page_num; /* current page number */ int s_H, s_V; /* H and V ints */ int s_resolution, s_horizontal, s_vertical; /* of typesetter */ } settings; typedef struct fontdes { tfont *tfontp; /* font entry */ uchar *widtab; /* width table */ uchar *kerntab; /* kerning table */ uchar *codetab; /* code table */ uchar *fitab; /* font index table */ int texfont[NSIZES]; /* number of font in DVI file */ } fontdes; /* define some macros for convenient reference to fields */ #define n_width tfontp->nwfont /* first thing in font entry */ #define font_name tfontp->namefont /* array of char */ #define int_name tfontp->intname /* array of char */ extern tdev dev; extern int halfwidth; extern short *pstab; extern lookup *specialtab; extern settings engine; /* where we are at now */ extern fontdes fonts[NFONTS]; SHAR_EOF if test 2724 -ne "`wc -c 'ditdvi.h'`" then echo shar: error transmitting "'ditdvi.h'" '(should have been 2724 characters)' fi echo shar: extracting "'dvi.c'" '(3825 characters)' if test -f 'dvi.c' then echo shar: over-writing existing file "'dvi.c'" fi cat << \SHAR_EOF > 'dvi.c' #include <stdio.h> #include "dvi.h" /* ** Code generation routines for DVI ** See dvitype.web in TeX sources for description of DVI format. */ int filepos = 0; static int postpos; static put1(c) int c; { putchar(c); ++filepos; } static put2(c) int c; { put1((c >> 8) & 0xff); put1(c & 0xff); } static put3(c) int c; { put1((c >> 16) & 0xff); put1((c >> 8) & 0xff); put1(c & 0xff); } static put4(c) int c; { put1((c >> 24) & 0xff); put1((c >> 16) & 0xff); put1((c >> 8) & 0xff); put1(c & 0xff); } set_char(c) int c; { if (0 <= c && c < 128) put1(SET_CHAR + c); else if (128 <= c && c < 256) { put1(SET1); put1(c); } else if (256 <= c && c < 65536) { put1(SET2); put2(c); } else if (65536 <= c && c < (1 << 24)) { put1(SET3); put3(c); } else { put1(SET4); put4(c); } } set_rule(a, b) int a, b; { put1(SET_RULE); put4(a); put4(b); } put_char(c) int c; { if (0 <= c && c < 256) { put1(PUT1); put1(c); } else if (256 <= c && c < 65536) { put1(PUT2); put2(c); } else if (65536 <= c && c < (1 << 24)) { put1(PUT3); put3(c); } else { put1(PUT4); put4(c); } } put_rule(a, b) int a, b; { put1(PUT_RULE); put4(a); put4(b); } int bop(counts, backptr) int counts[]; int backptr; { register int i, prev; prev = filepos; put1(BOP); for (i = 0; i < 10; ++i) put4(counts[i]); put4(backptr); return (prev); /* return position of this bop */ } eop() { put1(EOP); } push() { put1(PUSH); } pop() { put1(POP); } right(x) int x; { if (-128 <= x && x < 128) { put1(RIGHT1); put1(x & 0xff); } else if (-32768 <= x && x < 32768) { put1(RIGHT2); put2(x & 0xffff); } else if (-(1 << 23) <= x && x < (1 >> 23)) { put1(RIGHT3); put3(x & 0xffffff); } else { put1(RIGHT4); put4(x); } } down(y) int y; { if (-128 <= y && y < 128) { put1(DOWN1); put1(y & 0xff); } else if (-32768 <= y && y < 32768) { put1(DOWN2); put2(y & 0xffff); } else if (-(1 << 23) <= y && y < (1 >> 23)) { put1(DOWN3); put3(y & 0xffffff); } else { put1(DOWN4); put4(y); } } fnt_num(n) int n; { if (0 <= n && n < 64) put1(FNT_NUM + n); else if (64 <= n && n <= 256) { put1(FNT1); put1(n); } else if (256 <= n && n <= 65536) { put1(FNT2); put2(n); } else if (65536 <= n && n <= (1 >> 24)) { put1(FNT3); put3(n); } else { put1(FNT4); put4(n); } } xxx(s) char *s; { register int len = strlen(s); if (0 <= len && len < 256) { put1(XXX1); put1(len); } /* use only XXX1 and XXX4 else if (256 <= len && len < 65536) { put1(XXX2); put2(len); } else if (65536 <= len && len < (1 << 24)) { put1(XXX3); put3(len); */ else { put1(XXX4); put4(len); } while (*s != '\0') put1(*s++); } fnt_def(k, c, s, d, a, l) int k, c, s, d; char *a, *l; { register int la = strlen(a), ll = strlen(l); if (0 <= k && k < 256) { put1(FNT_DEF1); put1(k); } else if (256 <= k && k < 65536) { put1(FNT_DEF2); put2(k); } else if (65536 <= k && k < (1 >> 24)) { put1(FNT_DEF3); put3(k); } else { put1(FNT_DEF4); put4(k); } put4(c); put4(s); put4(d); put1(la); put1(ll); while (*a != '\0') put1(*a++); while (*l != '\0') put1(*l++); } pre(num, den, mag, k) int num, den, mag; char *k; { register int len = strlen(k); put1(PRE); put1(DVI_VERSION); put4(num); put4(den); put4(mag); put1(len); while (*k != '\0') put1(*k++); } post(back, num, den, mag, height, width, stack, pages) { postpos = filepos; put1(POST); put4(back); put4(num); put4(den); put4(mag); put4(height); put4(width); put2(stack); put2(pages); } post_post() { register int i; put1(POST_POST); put4(postpos); put1(DVI_VERSION); for (i = 0; i < 4; ++i) put1(SIGNATURE); while ((filepos & 0x3) != 0) put1(SIGNATURE); } SHAR_EOF if test 3825 -ne "`wc -c 'dvi.c'`" then echo shar: error transmitting "'dvi.c'" '(should have been 3825 characters)' fi echo shar: extracting "'dvi.h'" '(1103 characters)' if test -f 'dvi.h' then echo shar: over-writing existing file "'dvi.h'" fi cat << \SHAR_EOF > 'dvi.h' #define DVI_VERSION 2 #define SET_CHAR 0 #define SET1 128 #define SET2 129 #define SET3 130 #define SET4 131 #define SET_RULE 132 #define PUT1 133 #define PUT2 134 #define PUT3 135 #define PUT4 136 #define PUT_RULE 137 #define NOP 138 #define BOP 139 #define EOP 140 #define PUSH 141 #define POP 142 #define RIGHT1 143 #define RIGHT2 144 #define RIGHT3 145 #define RIGHT4 146 #define W0 147 #define W1 148 #define W2 149 #define W3 150 #define W4 151 #define X0 152 #define X1 153 #define X2 154 #define X3 155 #define X4 156 #define DOWN1 157 #define DOWN2 158 #define DOWN3 159 #define DOWN4 160 #define Y0 161 #define Y1 162 #define Y2 163 #define Y3 164 #define Z0 166 #define Z1 167 #define Z2 168 #define Z3 169 #define Z4 170 #define FNT_NUM 171 #define FNT1 235 #define FNT2 236 #define FNT3 237 #define FNT4 238 #define XXX1 239 #define XXX2 240 #define XXX3 241 #define XXX4 242 #define FNT_DEF1 243 #define FNT_DEF2 244 #define FNT_DEF3 245 #define FNT_DEF4 246 #define PRE 247 #define POST 248 #define POST_POST 249 #define SIGNATURE 223 SHAR_EOF if test 1103 -ne "`wc -c 'dvi.h'`" then echo shar: error transmitting "'dvi.h'" '(should have been 1103 characters)' fi echo shar: extracting "'fontfile.c'" '(4416 characters)' if test -f 'fontfile.c' then echo shar: over-writing existing file "'fontfile.c'" fi cat << \SHAR_EOF > 'fontfile.c' #include <stdio.h> #include "ditdvi.h" /* ** Routines to read ditroff DESC file. */ tdev dev; int halfwidth; short *pstab; lookup *specialtab; fontdes fonts[NFONTS]; static char *smalloc(n) int n; /* ** Get memory, or die */ { register char *p; char *malloc(); if ((p = malloc(n)) == NULL) fatal("No more memory\n"); return (p); } int readfontdir() /* ** Read in the information from the DESC file, storing it in ** the font info array. */ { register int i; register char *filedata, *chname; register short *chtab; register FILE *f; char fname[100]; char *sprintf(); (void)sprintf(fname, "%s/dev%s/DESC.out", FONTDIR, engine.s_ts_name); if ((f = fopen(fname, "r")) == NULL) { perror(fname); return (0); } if (fread((char *)&dev, sizeof(char), sizeof(tdev), f) != sizeof(tdev)) return (0); halfwidth = dev.unitwidth / 2; if (dev.nfonts >= NFONTS) fatal("Font capacity of %d fonts exceeded, reconfigure\n", NFONTS - 1); if (dev.nsizes >= NSIZES) fatal("Pointsize capacity of %d sizes exceeded, reconfigure\n", NSIZES); for (i = 0; i < NFONTS; ++i) /* zero descriptors */ { register fontdes *f; register int j; f = &fonts[i]; f->tfontp = (tfont *)0; f->codetab = f->fitab = (uchar *)0; for (j = 0; j < NSIZES; ++j) f->texfont[j] = -1; /* initially unloaded */ } filedata = smalloc(dev.filesize); if (fread(filedata, sizeof(char), dev.filesize, f) != dev.filesize) fatal("Short read on %s\n", fname); (void)fclose(f); pstab = (short *)filedata; filedata += (dev.nsizes + 1) * sizeof(short); chtab = (short *)filedata; filedata += dev.nchtab * sizeof(short); chname = filedata; filedata += dev.lchname; makespecialtab(dev.nchtab, chname, chtab); #ifdef DEBUG_FONTS dumptables(); #endif DEBUG_FONTS for (i = 1; i <= dev.nfonts; i++) { register int nw; fonts[i].tfontp = (tfont *)filedata; nw = fonts[i].n_width; filedata += sizeof(tfont); fonts[i].widtab = (uchar *)filedata; filedata += nw; fonts[i].kerntab = (uchar *)filedata; filedata += nw; fonts[i].codetab = (uchar *)filedata; filedata += nw; fonts[i].fitab = (uchar *)filedata; filedata += dev.nchtab + (128 - 32); } #ifdef DEBUG_FONTS dumpfonts(); #endif DEBUG_FONTS return (1); } static int speccmp(l1, l2) lookup *l1, *l2; { return (strcmp(l1->chname, l2->chname)); } makespecialtab(nspecials, strings, offsets) int nspecials; char *strings; short offsets[]; { register int i; specialtab = (lookup *)smalloc(nspecials * sizeof(lookup)); for (i = 0; i < nspecials; ++i) { specialtab[i].ordinal = i; specialtab[i].chname = strings + offsets[i]; } qsort((char *)specialtab, nspecials, sizeof(lookup), speccmp); #ifdef DEBUG_FONTS for (i = 0; i < nspecials; ++i) printf("%s %d\n", specialtab[i].chname, specialtab[i].ordinal); #endif DEBUG_FONTS } #ifdef DEBUG_FONTS static dumptables() /* ** Print font size tables */ { register int i; printf("Point size table\n"); for (i = 0; i <= dev.nsizes; ++i) { printf("%3d", pstab[i]); if (i % 20 == 19) putchar('\n'); else putchar(' '); } putchar('\n'); printf("Special chars\n"); for (i = 0; i < dev.nchtab; ++i) { printf("%s", &chname[chtab[i]]); if (i % 20 == 19) putchar('\n'); else putchar(' '); } putchar('\n'); } static dumpfonts() /* ** Print out a human readable representation of fonts for ** debugging purposes. */ { register int i; for (i = 1; i < NFONTS; ++i) { if (fonts[i].tfontp != NULL) dumponefont(i); } } static dumponefont(n) int n; /* ** Say all we know about this font */ { register tfont *tf; register uchar *t; register int i, nw; tf = fonts[n].tfontp; printf("%s (%s), %d entries,%s%s\n", tf->namefont, tf->intname, (int)tf->nwfont, tf->specfont ? " special" : " ", tf->ligfont ? " ligatures" : " "); nw = tf->nwfont; t = fonts[n].widtab; printf("Width table\n"); for (i = 0; i < nw; ++i) { printf("%3d", t[i]); if (i % 20 == 19) putchar('\n'); else putchar(' '); } putchar('\n'); t = fonts[n].codetab; printf("Code table\n"); for (i = 0; i < nw; ++i) { printf("%3d", t[i]); if (i % 20 == 19) putchar('\n'); else putchar(' '); } putchar('\n'); t = fonts[n].fitab; printf("Font index table\n"); for (i = 0; i < dev.nchtab; ++i) { printf("%3d", t[i]); if (i % 20 == 19) putchar('\n'); else putchar(' '); } putchar('\n'); } #endif DEBUG_FONTS SHAR_EOF if test 4416 -ne "`wc -c 'fontfile.c'`" then echo shar: error transmitting "'fontfile.c'" '(should have been 4416 characters)' fi echo shar: extracting "'getspecials'" '(191 characters)' if test -f 'getspecials' then echo shar: over-writing existing file "'getspecials'" fi cat << \SHAR_EOF > 'getspecials' #! /bin/sh # # This shell script extracts all the two character sequences for # inclusion in the DESC file # cat cm*10 \ | sed -e '/ .$/d' -e '/^.$/d' -e '/^..$/d' -e 's/.* //' \ | sort -u SHAR_EOF if test 191 -ne "`wc -c 'getspecials'`" then echo shar: error transmitting "'getspecials'" '(should have been 191 characters)' fi chmod +x 'getspecials' echo shar: extracting "'reader.c'" '(10736 characters)' if test -f 'reader.c' then echo shar: over-writing existing file "'reader.c'" fi cat << \SHAR_EOF > 'reader.c' #include <stdio.h> #include <ctype.h> #include "ditdvi.h" /* ** The heart of the converter, read ditroff, spit out DVI. */ #undef DEBUG_INPUT #undef USE_PUT /* same values as TeX82 uses */ #define FIX (1<<16) #define CPIN 7227 /* centipoints in an inch */ #define NUM 25400000 #define DEN (CPIN*FIX) #define UNITY 1000 /* paper dimensions */ #define HEIGHT (11*72*FIX) /* height in scaled pts */ #define WIDTH (17*36*FIX) /* width in scaled pts */ /* goobies to scaled points */ #define gtosp(g) ((g)*scale) #define vmove(n) down(gtosp(n)), engine.s_V += (n) settings engine = { DEF_DEV, "R", /* s_ts_name, s_font_name */ 0, 0, /* s_font_num, s_point_size */ 0, /* s_point_index */ 0, /* s_page_num */ 0, 0, /* s_H, s_V */ 0, 0, 0, /* resolution, horizontal, vertical */ }; int counters[10] = { 0 }; int scale = 0; int last_move = 0; char fontchanged = 0; int mag = UNITY; int back = -1; /* back pointer for bop */ char bopsent = 0; int fontind = 0; struct fonttab { int font; int size; } fonttab[NFONTS]; static int getnum() { register int i, c; while (isspace(c = getchar())) ; (void)ungetc(c, stdin); for (i = 0; isdigit(c = getchar()); ) i = i * 10 + c - '0'; (void)ungetc(c, stdin); return (i); } static int getint() { register int i; register char c, flag = 0; while (isspace(c = getchar())) ; if (c == '-') flag = 1; else (void)ungetc(c, stdin); for (i = 0; isdigit(c = getchar()); ) i = i * 10 + c - '0'; (void)ungetc(c, stdin); return (flag ? -i : i); } static resolve_name(font, size, name, newmag) char *name; int font, size; double *newmag; { char *index(); *newmag = 1.0; (void)strcpy(name, fonts[font].int_name); if (size <= 10) { /* stop at first digit */ for ( ; *name != '\0'; ++name) if (isdigit(*name)) break; /* overlay the size spec */ (void)sprintf(name, "%d", size); } else switch (size) { case 11: *newmag = 1.095445; break; case 12: *newmag = 1.2; break; case 14: *newmag = 1.44; break; case 17: *newmag = 1.728; break; case 24: case 25: *newmag = 2.48832; break; default: (void)fprintf(stderr, "Can't handle point size %d\n", size); break; } } static loadfont(font, sizeindex) int font, sizeindex; { register int size = pstab[sizeindex]; double newmag; char fontfile[256]; fontchanged = 0; /* defined yet? */ if (fonts[font].texfont[sizeindex] < 0) { resolve_name(font, size, fontfile, &newmag); fnt_def(fontind, 0, (int)(newmag * (double)(size * (1<<16))), size * (1<<16), "", fontfile); fonttab[fontind].font = font; fonttab[fontind].size = size; fonts[font].texfont[sizeindex] = fontind++; } fnt_num(fonts[font].texfont[sizeindex]); } static outchar(ch) int ch; { register int c, i, index, code, width; register fontdes *f; register int savedfont = -1; #ifdef DEBUG_OUTPUT (void)fprintf(stderr, "<%c>\n", ch); #endif DEBUG_OUTPUT c = ch - 32; f = &fonts[engine.s_font_num]; index = f->fitab[c]; /* char to index */ if (index != 0) { code = f->codetab[index]; width = f->widtab[index]; } else /* a special then */ { for (i = 1; i <= dev.nfonts; ++i) { f = &fonts[i]; if (!f->tfontp->specfont) continue; if (f->fitab == 0) /* font not available */ continue; if ((index = f->fitab[c]) != 0) { savedfont = engine.s_font_num; engine.s_font_num = i; fontchanged = 1; code = f->codetab[index]; width = f->widtab[index]; break; } } } if (index != 0) { if (fontchanged) loadfont(engine.s_font_num, engine.s_point_index); /* ** Rule height is roughly 1/18th of point size */ #ifdef USE_PUT if (code != RULE_CHAR) put_char(code); else put_rule(gtosp(engine.s_resolution * engine.s_point_size / (72 * 18)), gtosp(width)); #else if (code != RULE_CHAR) set_char(code); else set_rule(gtosp(engine.s_resolution * engine.s_point_size / (72 * 18)), gtosp(width)); last_move += (width * engine.s_point_size + halfwidth) / dev.unitwidth; #endif if (savedfont >= 0) { engine.s_font_num = savedfont; fontchanged = 1; } } else if (ch != ' ') /* kludge, space glyph not in fonts */ (void)fprintf(stderr, "Font %s, glyph %d not found\n", fonts[engine.s_font_num].font_name, ch); } static outstring(s) char *s; { register int low, mid, high; register char *t, *m; #ifdef DEBUG_OUTPUT (void)fprintf(stderr, "<%s>\n", s); #endif DEBUG_OUTPUT low = 0; high = dev.nchtab - 1; while (low <= high) { mid = (low + high) / 2; t = s; m = specialtab[mid].chname; while (*t == *m && *t != '\0') ++t, ++m; if (*t > *m) low = mid + 1; else if (*t < *m) high = mid - 1; else /* equal, found it */ { outchar(specialtab[mid].ordinal + 128); break; } } } static hmove(n) int n; { engine.s_H += n; if (n == last_move) { last_move = 0; return; } n -= last_move; last_move = 0; right(gtosp(n)); } static hgoto(n) int n; { #ifdef USE_PUT engine.s_H += last_move; last_move = 0; if (n == engine.s_H) return; hmove(n - engine.s_H); #else pop(); push(); down(gtosp(engine.s_V)); right(gtosp(n)); engine.s_H = n; last_move = 0; #endif } static vgoto(n) int n; { if (n == engine.s_V) return; vmove(n - engine.s_V); } static specialchar() { register char c, *p; char special[10]; for (p = special; isprint(c = getchar()); ) *p++ = c; *p = '\0'; outstring(special); } static finishpage() { /* finish previous page */ if (bopsent) { pop(); eop(); ++engine.s_page_num; } bopsent = 0; } static newpage(n) { finishpage(); last_move = engine.s_H = engine.s_V = 0; counters[0] = n; back = bop(counters, back); /* DVI output origin is at (1in,1in), need to cancel */ if (pageoffset) { down(-CPIN * FIX / 100); /* up 1 in */ right(-CPIN * FIX / 100); /* left 1 in */ } push(); bopsent = 1; } static nextword() { register int c; while (!isspace(getchar())) ; while (isspace(c = getchar())) ; (void)ungetc(c, stdin); } static getstring(s, len) char *s; int len; { register char c; --len; /* for the '\0' terminator */ while (len > 0 && !isspace(c = getchar())) *s++ = c; *s = '\0'; } /* ** If you expect to load fonts above ditroff's limit of 10 ** you may need this routine. */ static fontposition(i, s) int i; char *s; { } static postamble() { register int i; double newmag; char fontfile[256]; finishpage(); /* ship off pending page */ /* we use one level of stack */ post(back, NUM, DEN, mag, HEIGHT, WIDTH, 1, engine.s_page_num); for (i = 0; i < fontind; ++i) { register struct fonttab *ft = &fonttab[i]; resolve_name(ft->font, ft->size, fontfile, &newmag); fnt_def(i, 0, (int)(newmag * (double)(ft->size * (1<<16))), ft->size * (1<<16), "", fontfile); } post_post(); } static setfontsize(n) int n; { register int i; for (i = 0; i < dev.nsizes; ++i) if (pstab[i] == n) break; if (i >= dev.nsizes) { (void)fprintf(stderr, "%d is not a legal point size\n", n); return; } engine.s_point_size = n; engine.s_point_index = i; } static int devcntl() { register char c; register int i; char comment[256]; char fontname[256]; while (isspace(c = getchar())) ; switch (c) { case 'i': /* initialize */ nextword(); (void)sprintf(comment, "Generated by %s from ditroff output for %s at resolution %d", prog_name, engine.s_ts_name, engine.s_resolution); if (!readfontdir()) fatal("Can't read DESC file\n"); pre(NUM, DEN, mag, comment); break; case 'T': /* typesetter name */ nextword(); getstring(engine.s_ts_name, sizeof(engine.s_ts_name)); break; case 'r': /* resolution */ nextword(); engine.s_resolution = getnum(); if (engine.s_resolution <= 0) fatal("Resolution should be positve, is %d\n", engine.s_resolution); scale = 72 * (1<<16) / engine.s_resolution; engine.s_horizontal = getnum(); engine.s_vertical = getnum(); break; case 'p': /* pause */ break; case 's': /* stop */ nextword(); postamble(); return(1); case 't': /* trailer */ nextword(); break; case 'f': /* associate font with number */ nextword(); i = getnum(); nextword(); getstring(fontname, sizeof(fontname)); fontposition(i, fontname); break; case 'H': /* set character height */ break; case 'S': /* set slant */ break; default: fatal("Unknown device control %c\n", c); break; } return (0); } static graphics() /* ** Conversion to tpic output left as an exercise for hacker. ** Should generate xxx commands in DVI. */ { register char c; register int p1, p2, p3; switch (c = getchar()) { case 'l': break; case 'c': break; case 'e': break; case 'a': break; case '~': break; default: fatal("Unknown drawing function %c\n", c); break; } /* eat up the rest of the line */ while (getchar() != '\n') ; } reader() /* ** Switch to appropriate routine depending on character read in */ { register int c; while ((c = getchar()) != EOF) { #ifdef DEBUG_INPUT (void)fprintf(stderr, "%c", c); #endif DEBUG_INPUT /* ** The code generated by pcc for switch statements is sufficiently ** inefficient to take out the most common cases. (Loop to match, gag!) */ if (c == 'h') /* this is used often enough to justify making it inline instead of calling getnum */ { register int hmotion; for (hmotion = 0; isdigit(c = getchar()); ) hmotion = hmotion * 10 + c - '0'; (void)ungetc(c, stdin); hmove(hmotion); } else if (c == 'c') outchar(getchar()); else if (isdigit(c)) { register int hmotion; register char c1; if (!isdigit(c1 = getchar())) { fatal("Non-digit in nn\n"); return; } hmotion = (c - '0') * 10 + c1 - '0'; hmove(hmotion); outchar(getchar()); } /* for the less common cases we can afford some inefficiency */ else switch (c) { case 'H': hgoto(getnum()); break; case 'v': vmove(getnum()); break; case 'V': vgoto(getint()); break; case 'C': specialchar(); break; case 's': setfontsize(getnum()); fontchanged = 1; break; case 'f': engine.s_font_num = getnum(); engine.s_font_name = fonts[engine.s_font_num].font_name; fontchanged = 1; break; case 'p': newpage(getnum()); break; case 'n': (void)getnum(); /* no action required */ (void)getnum(); break; case 'w': break; /* no action required */ case 'x': if (devcntl()) /* stop? */ return; break; case 'D': graphics(); break; case '\0': /* discard whitespace and noise */ case ' ': case '\n': break; default: fatal("Unrecognized ditroff command: %c\n", c); break; } } } SHAR_EOF if test 10736 -ne "`wc -c 'reader.c'`" then echo shar: error transmitting "'reader.c'" '(should have been 10736 characters)' fi echo shar: extracting "'tfm2desc.1'" '(2653 characters)' if test -f 'tfm2desc.1' then echo shar: over-writing existing file "'tfm2desc.1'" fi cat << \SHAR_EOF > 'tfm2desc.1' .TH TFM2DESC 1 4/9/88 .CM 1 .SH "NAME" tfm2desc \- generate ditroff font description file from TeX tfm file .SH "SYNOPSIS" tfm2desc [\fB\-ddesignsize\fP] [\fB\-sspacewidth\fP] \fItfmprefix\fP [type] .SH "DESCRIPTION" \fITfm2desc\fP is a program to generate typesetter description files from tfm files. The typesetter being described is a virtual one, since the DESC file will be used with \fIditroff\fP and \fIditdvi\fP. .PP The file argument is the name of a file in the current directory with the following data: The first line is the name of the \fIditroff\fP font, e.g. R. Each succeeding lines describes one character. The line contains the octal code and the one- or two character sequence for the glyph, separated by a tab. Adjacent duplicate octal codes can be used to specify characters with one or more synonyms and will generate ``ditto'' lines in the output file. .PP \fItfm2desc\fP reads the tfm file named TEXFONT/tfmprefix.tfm. TEXFONT is a #define'd string in the source you can change. The metrics go to standard output. These should go to a file of the same name as the first line of the input file. The output should then be processed by \fImakedev\fP. .PP The \fB\-d\fP flag specifies an alternate design size instead of that in the tfm file. All widths will be scaled accordingly. This allows you to make the widths as large as possible but they should be less than 256 (the limit imposed by \fIditroff\fP). Large width entries minimize the roundoff error in the widths. The design size will be written on the unitwidth line in the output file. .PP The \fB\-s\fP flag specifies the spacewidth line in the output file. .PP \fItype\fP is an optional single letter which is either m or s, meaning monospaced or special (\fIditroff\fP terminology). No ligature entries will be generated for these fonts. The special line will be put in the output file for special fonts. .PP The #define'd constant RESOLUTION should match that in the DESC file. Since the printer is imaginary, the choice is arbitrary, subject to constraints imposed on the unitwidth and width entries. As distributed, 576 units per inch is used. .SH "FILES" /usr/lib/tex/fonts directory where the tfm files live .SH "SEE ALSO" ditroff(1), makedev(1), ditdvi(1) .SH "DIAGNOSTICS" Hopefully self-explanatory. .SH "BUGS" Contains hacks to deal with the 1/6 and 1/12 em spacing characters and the baseline rule. These should be placed in positions 128 and above because all the lower 128 positions are occupied in TeX fonts. \fIDitdvi\fP knows about this hack. .SH "ACKNOWLEDGEMENT" This program borrows ideas and some code from \fItfm2difont\fP, written by Scott Simpson. SHAR_EOF if test 2653 -ne "`wc -c 'tfm2desc.1'`" then echo shar: error transmitting "'tfm2desc.1'" '(should have been 2653 characters)' fi echo shar: extracting "'tfm2desc.c'" '(6358 characters)' if test -f 'tfm2desc.c' then echo shar: over-writing existing file "'tfm2desc.c'" fi cat << \SHAR_EOF > 'tfm2desc.c' #include <stdio.h> /* ** Get character widths out of tfm files. See man page. */ /* where the TeX tfm files live */ #ifndef TEXFONT #define TEXFONT "/usr/lib/tex/fonts/" #endif #define FIX (1<<20) #define UNKNOWN (-1) #define PPI 72 #ifndef RESOLUTION #define RESOLUTION (PPI*8) #endif #define HEADERSIZE 24 int designsize = 0; int spacewidth = -1; usage() { (void)fprintf(stderr, "Usage: tfm2desc [-d<ds>] [-s<sw>] fontmap [m|s]\n"); exit(1); } main(argc,argv) int argc; char *argv[]; { register int c; register char type = ' '; char tfmname[256]; char extname[10]; FILE *tfmfile; extern int optind; extern char *optarg; int getopt(), atoi(); while ((c = getopt(argc, argv, "d:s:")) != EOF) { switch (c) { case 'd': designsize = atoi(optarg); if (designsize <= 0) (void)fprintf(stderr, "Bad designsize: %d, will use designsize in tfm file\n", designsize); break; case 's': spacewidth = atoi(optarg); break; default: exit(1); break; } } argc -= optind; argv += optind; if (argc < 1) usage(); if (freopen(argv[0], "r", stdin) == NULL) { perror(argv[0]); exit(1); } (void)sprintf(tfmname, "%s%s.tfm", TEXFONT, argv[0]); if ((tfmfile = fopen(tfmname, "r")) == NULL) { perror(argv[0]); exit(1); } (void)fgets(extname, sizeof(extname), stdin); if (extname[1] == '\n') extname[1] = '\0'; if (extname[2] == '\n') extname[2] = '\0'; if (argc >= 2) type = argv[1][0]; convert(extname, argv[0], tfmfile, type); exit(0); } #define get1(buffer, offset) (buffer[offset]) int get2(buffer, offset) unsigned char *buffer; int offset; { return ((buffer[offset] << 8) | buffer[offset + 1]); } int get4(buffer, offset) unsigned char *buffer; int offset; { register int i, n; n = 0; for (i = 0; i < 4; ++i) n = (n << 8) | buffer[offset + i]; return (n); } /* ** Convert from FIXES to pixels. The roundoff error of this ** routine is a max of (72*designsize)/2^20, which is negligible ** for ordinary pointsizes. */ fixestopixels(fix, designsize) int fix; int designsize; { register unsigned long l; l = fix * RESOLUTION / PPI; l = (l * designsize + FIX / 2) / FIX; return (l); } /* ** The main routine which converts a tfm file to a troff width table file */ convert(extname, intname, tfmfile, type) char *extname, *intname; FILE *tfmfile; char type; { register int i, j, ch; register unsigned char *tfmbuf; register int aheight; int lh, bc, ec, nw, nh; char line[256]; char name[3]; char *malloc(); /* ** Read the whole tfm file in one gulp */ i = getc(tfmfile) & 0xff; i = (i << 8) | (getc(tfmfile) & 0xff); i *= 4; if ((tfmbuf = (unsigned char *)malloc(i)) == NULL) { (void)fprintf(stderr, "Out of memory\n"); exit(1); } i -= 2; if ((j = fread(tfmbuf + 2, sizeof(char), i, tfmfile)) != i) { (void)fprintf(stderr, "Short read on %s, want %d, got %d\n", intname, i, j); exit(1); } (void)printf("name %s\ninternalname %s\n", extname, intname); if (type == 's') (void)printf("special\n"); else if (type != 's' && type != 'm') /* not special or mono-spaced */ (void)printf("ligatures ff fi fl ffi ffl 0\n"); if (type != 's') { if ((aheight = getaheight(tfmbuf)) == UNKNOWN) { (void)fprintf(stderr, "No letter 'a' in %s.tfm\n", intname); (void)fprintf(stderr, "\tSetting height to zero\n"); aheight = 0; } } if (spacewidth >= 0) (void)printf("spacewidth %d\n", spacewidth); lh = get2(tfmbuf, 2) * 4; bc = get2(tfmbuf, 4); ec = get2(tfmbuf, 6); nw = get2(tfmbuf, 8) * 4; nh = get2(tfmbuf, 10) * 4; if (designsize <= 0) designsize = get4(tfmbuf, HEADERSIZE + 4) / FIX; (void)printf("charset\n"); ch = -1; while (fgets(line, sizeof(line), stdin) != NULL) { register int widthindex, heightanddepth, width; int height, depth, kerning; int temp; if (sscanf(line, "%o\t%2s\n", &temp, name) != 2) { (void)fprintf(stderr, "Bad spec file: %s", line); exit(1); } /* space is a terminator */ if (name[0] == '\0') { name[0] = ' '; name[1] = '\0'; } if (temp >= 128) { specials(name, temp, spacewidth); continue; } if (temp == ch) { (void)printf("%s\t\"\n", name); continue; } ch = temp; widthindex = get1(tfmbuf, HEADERSIZE + lh + (ch-bc)*4); heightanddepth = get1(tfmbuf, HEADERSIZE + lh + (ch-bc)*4 + 1); if (widthindex == 0) continue; width = get4(tfmbuf, HEADERSIZE + lh + (ec-bc+1)*4 + widthindex*4); width = fixestopixels(width, designsize); height = get4(tfmbuf, HEADERSIZE + lh + (ec-bc+1)*4 + nw + (heightanddepth>>4)*4); height = fixestopixels(height, designsize); depth = get4(tfmbuf, HEADERSIZE + lh + (ec-bc+1)*4 + nw + nh + (heightanddepth & 0xf)*4); depth = fixestopixels(depth, designsize); kerning = 0; if (height > aheight) kerning |= 2; if (depth > 0) kerning |= 1; if (width >= 256) (void)fprintf(stderr, "Warning: width of %d for %s is too wide for ditroff to handle\n", width, name); (void)printf("%s\t%d\t%d\t0%o\n", name, width, kerning, ch); } } /* Returns the height of the letter 'a' in the font passed as a parameter. * The height is returned in pixels since troff likes to use pixels as its * unit. If the letter 'a' is not found, UNKNOWN is returned. */ int getaheight(buffer) unsigned char *buffer; { register int lh, bc, ec, nw, designsize; register int widthindex, heightanddepth, height; lh = get2(buffer, 2) * 4; bc = get2(buffer, 4); ec = get2(buffer, 6); nw = get2(buffer, 8) * 4; if (bc > 'a' || ec < 'a') return (UNKNOWN); designsize = get4(buffer, HEADERSIZE + 4) / FIX; /* Convert from FIXes */ widthindex = get1(buffer, HEADERSIZE + lh + ('a'-bc)*4); heightanddepth = get1(buffer, HEADERSIZE + lh + ('a'-bc)*4 + 1); if (widthindex == 0) return (UNKNOWN); height = get4(buffer, HEADERSIZE + lh + (ec-bc+1)*4 + nw + (heightanddepth >> 4)*4); return (fixestopixels(height, designsize)); } specials(name, ch, width) char *name; int ch, width; { if (strcmp(name, "\\&") == 0) width = 0; /* assume em space is twice space width */ else if (strcmp(name, "\\^") == 0) width = (width + 3) / 6; /* 1/12 em space */ else if (strcmp(name, "\\|") == 0) width = (width + 1) / 3; /* 1/6 em space */ /* make ru same as spacewidth */ (void)printf("%s\t%d\t0\t0%o\n", name, width, ch); } SHAR_EOF if test 6358 -ne "`wc -c 'tfm2desc.c'`" then echo shar: error transmitting "'tfm2desc.c'" '(should have been 6358 characters)' fi # End of shell archive exit 0