v02i101: ditroff to DVI filter - ditdvi
Ken Yap
ken at rochester.UUCP
Thu Apr 21 09:27:23 AEST 1988
comp.sources.misc: Volume 2, Issue 101
Submitted-By: "Ken Yap" <ken at 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 at 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
More information about the Comp.sources.misc
mailing list