summaryrefslogtreecommitdiff
path: root/dviware/ln03/rose/dvi2ln3.lis
diff options
context:
space:
mode:
Diffstat (limited to 'dviware/ln03/rose/dvi2ln3.lis')
-rw-r--r--dviware/ln03/rose/dvi2ln3.lis1602
1 files changed, 1602 insertions, 0 deletions
diff --git a/dviware/ln03/rose/dvi2ln3.lis b/dviware/ln03/rose/dvi2ln3.lis
new file mode 100644
index 0000000000..b8c209889d
--- /dev/null
+++ b/dviware/ln03/rose/dvi2ln3.lis
@@ -0,0 +1,1602 @@
+
+DVI2LN3 14-OCT-1985 13:19:13 VAX C V2.0-003 Page 1
+V1.0 14-OCT-1985 13:19:01 USER$4:[TEX.LN03.SOURCES]DVI2LN3.C;40 (1)
+
+
+
+ 1 /* Dvi2ln3 translates a TeX DVI file to an LN03 format file.
+ 2
+ 3 Dvi2ln3 is still being developed. Copyright (c) 1985 by Digital Equipment
+ 4 Corporation, Maynard, Massachusetts, USA. Author: Flavio Rose,
+ 5 shasta!decwrl!dec-rhea!dec-dvinci!rose.
+ 6
+ 7 Dvi2ln3 is based on the publicly-available program DVItype, written by
+ 8 David R. Fuchs of Stanford University; and also on earlier DEC programs for
+ 9 the LN01 and LN03 laser printers, Dvi2lng, Topp and LN03Topp. This program
+ 10 is not a DEC product and is not guaranteed to work.
+ 11
+ 12 Dvi2ln3 is written in VAX C. Specific VAX and VMS dependencies have
+ 13 generally been avoided, however. The reader may find them by searching
+ 14 for the strings VAX and VMS in this file.
+ 15
+ 16 During development, double square brackets [[ ]] in a comment indicate some
+ 17 places where the code needs to be improved.
+ 18
+ 19 [[Among the useful things that still need to be done: differentiating
+ 20 between int and long variables so this can be ported more easily to 16-bit
+ 21 architectures; testing to see if malloc returns 0; a \special for ROM
+ 22 fonts; a \special for sixels.]]
+ 23
+ 24 Development history:
+ 25
+ 26 Feb. 85: Did some early work on Dvi2ln3, translating bits and pieces
+ 27 of Dvi2lng. Concluded, however, that it was better to translate
+ 28 LN03Topp and Dvi2lng into C first. The reason for this is that code
+ 29 which mimics an existing program is easier to write and to test.
+ 30
+ 31 5/15/85: At this date, the old LN03Topp program has been successfully
+ 32 translated into C (except for the ability to read files over
+ 33 DECnet). At this point, did some further cleanup of the Dvi2ln3
+ 34 source.
+ 35
+ 36 6/4/85: Coding of Dvi2ln3 begins in earnest. Merging bits and
+ 37 pieces from various places. Chucking chunks and all that
+ 38 junk from LN03Topp; pass2 is just straightforward translation.
+ 39
+ 40 6/22/85: Cleanup after initial debugging. Ready to distribute.
+ 41
+ 42 10/14/85: Bug in parsing of \special's. Version 1.
+ 43
+ 44 */
+ 45
+ 46 #include stdio
+ 104
+ 105 /* To please the VMS linker, we declare all global variables to be
+ 106 globaldef. This is done with #define's, so it may easily be undone when
+
+DVI2LN3 14-OCT-1985 13:19:13 VAX C V2.0-003 Page 2
+V1.0 14-OCT-1985 13:19:01 USER$4:[TEX.LN03.SOURCES]DVI2LN3.C;40 (1)
+
+ 107 porting the program to other systems. */
+ 108
+ 109 #ifdef vms
+ 110 #define GLOBAL globaldef
+ 111 #define EXTERN globalref
+ 112 #else
+ 113 X #define GLOBAL
+ 114 X #define EXTERN extern
+ 115 #endif
+ 116
+ 117 /* hoff is the horizontal offset in pixels to be added to all dimensions
+ 118 read in; voff is the corresponding vertical offset. */
+ 119
+ 120 GLOBAL int hoff, voff, startp;
+ 121 GLOBAL FILE *dvifile,*tfmfile,*outfile;
+ 122
+ 123 /* Each page in a DVI file is identified by ten longwords, which appear
+ 124 immediately after each bop (beginning of page) command. Dvi2ln3, like
+ 125 DVItype, supports certain options that allow one to print only selected
+ 126 pages. The following variables are used for this purpose.
+ 127
+ 128 Num_pages is a count of how many pages have been passed to the output.
+ 129 Max_pages is the user-specified maximum number of pages to pass.
+ 130 How_many_counts denotes the number of identifying longwords to take into
+ 131 account when searching for the user-specified starting page. The user
+ 132 specifies the starting page as the first one whose identifying longwords
+ 133 match certain specified values, stored in start_page. However, identifying
+ 134 longword i is only required to match the value in start_page[i] if
+ 135 use_count[i] is nonzero. */
+ 136
+ 137 GLOBAL long int num_pages,max_pages;
+ 138 GLOBAL int how_many_counts,use_count[10];
+ 139 GLOBAL long int start_page[10];
+ 140
+ 141 /* FILESPECLEN is the maximum size of a file specification under VMS.
+ 142 [[Perhaps arrays of fixed size should not be used, but rather malloc should
+ 143 be employed...]] */
+ 144
+ 145 #define FILESPECLEN 252
+ 146
+ 147 /* The main routine deals with the command line arguments, opens the dvi
+ 148 file, and then calls various other routines to handle the "passes". There
+ 149 are two passes which involve reading the DVI file; in between, the font
+ 150 load is constructed. */
+ 151
+ 152 main(argc,argv)
+ 153 int argc;
+ 154 char *argv[];
+ 155 {
+ 156 1 int status,i,jnam,jext;
+ 157 1 char infnam[FILESPECLEN];
+
+DVI2LN3 14-OCT-1985 13:19:13 VAX C V2.0-003 Page 3
+V1.0 14-OCT-1985 13:19:01 USER$4:[TEX.LN03.SOURCES]DVI2LN3.C;40 (1)
+
+ 158 1
+ 159 1 if (argc < 2) { printf("\n Usage: Dvi2ln3 <filename> <options>");
+ 160 2 goto exit_label; }
+ 161 1
+ 162 1 printf("\n Dvi2ln3 1");
+ 163 1
+ 164 1 strcpy(infnam,argv[1]);
+ 165 1
+ 166 1 /* The extension of the input file defaults to .dvi. Locate the filename
+ 167 1 field within the filespec parameter, set jname to point to beginning, jext
+ 168 1 to point to one place after end. [[This code is of course dependent on the
+ 169 1 VMS filespec syntax.]] */
+ 170 1
+ 171 1 find_VMS_filename(infnam,&jnam,&jext);
+ 172 1 if (infnam[jext] == '\0') strcat(infnam,".dvi");
+ 173 1 dvifile = fopen(infnam,"r");
+ 174 1 if (dvifile == NULL) { printf("\n Couldn't open dvi file");
+ 175 2 goto exit_label; }
+ 176 1
+ 177 1 /* Now decipher the options off the command line. */
+ 178 1
+ 179 1 max_pages = 1000000000;
+ 180 1 how_many_counts = 0;
+ 181 1 hoff = 300;
+ 182 1 voff = 300;
+ 183 1 for (i=2; i<argc; i++) command_line_options(argv[i]);
+ 184 1
+ 185 1 status = pass1();
+ 186 1 if (status != 0) goto exit_label;
+ 187 1 if (rewind(dvifile) == -1) {
+ 188 2 printf("\n Couldn't rewind dvi file.");
+ 189 2 goto exit_label;
+ 190 2 }
+ 191 1
+ 192 1 status = open_output_file(infnam,jnam,jext,".ln3");
+ 193 1 if (status != 0) { printf("\n Couldn't open output file");
+ 194 2 goto exit_label; }
+ 195 1
+ 196 1 status = make_font_load();
+ 197 1 if (status != 0) goto exit_label;
+ 198 1
+ 199 1 pass2();
+ 200 1
+ 201 1 fprintf(outfile,"\033c");
+ 202 1 fclose(dvifile);
+ 203 1 fclose(outfile);
+ 204 1
+ 205 1 exit_label:
+ 206 1 ;
+ 207 1 }
+ 208
+
+DVI2LN3 14-OCT-1985 13:19:13 VAX C V2.0-003 Page 4
+V1.0 14-OCT-1985 13:19:01 USER$4:[TEX.LN03.SOURCES]DVI2LN3.C;40 (1)
+
+ 209 /* Find_VMS_filename finds the filename part of a VMS filespec passed in s,
+ 210 returning the index of the first character in *ns, and the index of the
+ 211 character after the last in *ne.
+ 212
+ 213 [[When porting Dvi2ln3 to a non-VMS system, we need to find an alternative
+ 214 to this function. Under Unix, as a first approximation, we could look for
+ 215 the last "/" or "~" and then for the first succeeding "." in the filespec.
+ 216 Is this correct?]] */
+ 217
+ 218 int find_VMS_filename(s,ns,ne)
+ 219 char s[];
+ 220 int *ns,*ne;
+ 221 {
+ 222 1 int jnam,jext,j,slen;
+ 223 1
+ 224 1 slen = strlen(s);
+ 225 1 jnam = 0;
+ 226 1 for (j = slen-1; j >= 0; j--) {
+ 227 2 if (s[j] == ':' || s[j] == ']' ||
+ 228 2 s[j] == '>') {
+ 229 3 jnam = j+1;
+ 230 3 break;
+ 231 3 }
+ 232 2 }
+ 233 1
+ 234 1 jext = slen;
+ 235 1 for (j = jnam; j < slen; j++) {
+ 236 2 if (s[j] == '.' || s[j] == ';') {
+ 237 3 jext = j;
+ 238 3 break;
+ 239 3 }
+ 240 2 }
+ 241 1
+ 242 1 *ns = jnam;
+ 243 1 *ne = jext;
+ 244 1 }
+ 245
+ 246 /* ERROR HANDLING: Errors should be reported as close to the source as
+ 247 possible, so that the maximum amount of information is available to the
+ 248 user to identify the error.
+ 249
+ 250 Errors in the format of DVI or TFM files are not reported specifically,
+ 251 since there exist programs, DVItype and TFtoPL, which diagnose errors in
+ 252 such files. This program accepts some incorrect DVI files, for example,
+ 253 those with a bad postamble or bad backpointers. [[However, someday we may
+ 254 rewrite the program to select pages by using these features of the DVI
+ 255 format, rather than by skipping unwanted pages.]] */
+ 256
+ 257 GLOBAL char *bad_DVI_message = "\nBad DVI file - check it with DVItype";
+ 258
+ 259 /* Command_line_options reads and processes options off the string s. At
+
+DVI2LN3 14-OCT-1985 13:19:13 VAX C V2.0-003 Page 5
+V1.0 14-OCT-1985 13:19:01 USER$4:[TEX.LN03.SOURCES]DVI2LN3.C;40 (1)
+
+ 260 this time, four options are supported.
+ 261
+ 262 The N option sets the maximum number of pages to be printed. Its syntax is
+ 263 /N=<integer> .
+ 264
+ 265 The H option modifies the default horizontal offset.
+ 266
+ 267 The V option modifies the default vertical offset.
+ 268
+ 269 The S option has syntax /S=<pagespec>{.<pagespec>}* where the {}* denotes
+ 270 repetition, and a <pagespec> is either an integer or * to indicate any
+ 271 value. An example would be "/S=*.8.3".
+ 272
+ 273 The meaning of the S option is as follows: In a DVI file, pages are
+ 274 identified by ten longword values which follow each bop (beginning of page)
+ 275 command. The value of the S option indicates which page to start printing
+ 276 on. For example, "*.8.3" means start printing at the first page whose
+ 277 second identifying longword is 8 and third is 3. */
+ 278
+ 279 int command_line_options(t)
+ 280 char *t;
+ 281 {
+ 282 1 long int i,k;
+ 283 1 char *u;
+ 284 1
+ 285 1 while ((t = strchr(t,'/')) != 0) {
+ 286 2 t++;
+ 287 2 if (toupper(t[0]) == 'N' && t[1] == '='
+ 288 2 && (sscanf(&t[2],"%ld",&k) == 1))
+ 289 2 max_pages = k;
+ 290 2 if (toupper(t[0]) == 'H' && t[1] == '='
+ 291 2 && (sscanf(&t[2],"%ld",&k) == 1))
+ 292 2 hoff = k;
+ 293 2 if (toupper(t[0]) == 'V' && t[1] == '='
+ 294 2 && (sscanf(&t[2],"%ld",&k) == 1))
+ 295 2 voff = k;
+ 296 2 else if (toupper(t[0]) == 'S' && t[1] == '=') {
+ 297 3 t += 2;
+ 298 3 how_many_counts = 0;
+ 299 3 for (;;) {
+ 300 4 if (t[0] == '*') {
+ 301 5 use_count[how_many_counts] = 0;
+ 302 5 how_many_counts++;
+ 303 5 }
+ 304 4 else if (sscanf(t,"%ld",&k) != 0) {
+ 305 5 use_count[how_many_counts] = 1;
+ 306 5 start_page[how_many_counts] = k;
+ 307 5 how_many_counts++;
+ 308 5 } else break;
+ 309 4 u = strchr(t,'.');
+ 310 4 if (u == 0) break;
+
+DVI2LN3 14-OCT-1985 13:19:13 VAX C V2.0-003 Page 6
+V1.0 14-OCT-1985 13:19:01 USER$4:[TEX.LN03.SOURCES]DVI2LN3.C;40 (1)
+
+ 311 4 t = &u[1];
+ 312 4 }
+ 313 3 }
+ 314 2 }
+ 315 1 }
+ 316
+ 317 /* Open_output_file opens one of the output files, using the file pointer
+ 318 outfile. The name of the output file is obtained by appending the string
+ 319 ext to the substring of infnam beginning at jnam and ending at jext.
+ 320
+ 321 [[This code contains a VMS depndency. We use creat followed by fdopen to
+ 322 open the file as a normal VMS file ("rat=cr","rfm=var") rather than a
+ 323 STREAM_LF file. Beginning with VAX C V2.0, this can be done by just calling
+ 324 fopen.]] */
+ 325
+ 326 int open_output_file(infnam,jnam,jext,ext)
+ 327 char *infnam,*ext;
+ 328 int jnam,jext;
+ 329 {
+ 330 1 char outfnam[FILESPECLEN];
+ 331 1 int jj;
+ 332 1
+ 333 1 strcpy(outfnam,&infnam[jnam]);
+ 334 1 strcpy(&outfnam[jext-jnam],ext);
+ 335 1
+ 336 1 jj = creat(outfnam,0,"rat=cr","rfm=var");
+ 337 1 if (jj == -1) return(1);
+ 338 1 outfile = fdopen(jj,"w");
+ 339 1 if (outfile == NULL) return(1);
+ 340 1
+ 341 1 return(0);
+ 342 1 }
+ 343
+ 344 /* Bytes are read one by one from the DVI file using getc. We use an
+ 345 overlay, as suggested in the DVItype documentation, to combine these bytes
+ 346 into larger integers. [[Note that this technique relies on the fact that
+ 347 numbers on the VAX are stored with the least significant byte first. The
+ 348 macros below would have to be changed if the program were to be ported to a
+ 349 machine architecture for which this is not so.]]
+ 350
+ 351 [[The use of getc is expensive, since getc is a function in VAX C V2.0.
+ 352 Eventually, one would want to rewrite these macros to work like the old
+ 353 getc macro.]] */
+ 354
+ 355 GLOBAL union lc { long int l; unsigned long int ul; char c[4];
+ 356 unsigned char uc[4]; } lcx;
+ 357
+ 358 #define two_bytes_u lcx.uc[1] = getc(dvifile); \
+ 359 lcx.uc[0] = getc(dvifile); lcx.uc[2] = 0; lcx.uc[3] = 0
+ 360
+ 361 #define two_bytes_s lcx.c[1] = getc(dvifile); \
+
+DVI2LN3 14-OCT-1985 13:19:13 VAX C V2.0-003 Page 7
+V1.0 14-OCT-1985 13:19:01 USER$4:[TEX.LN03.SOURCES]DVI2LN3.C;40 (1)
+
+ 362 lcx.c[0] = getc(dvifile); \
+ 363 if (lcx.c[1] >= 0) { lcx.uc[2] = 0; lcx.uc[3] = 0 ;} \
+ 364 else { lcx.uc[2] = 255; lcx.uc[3] = 255; }
+ 365
+ 366 #define three_bytes_u lcx.uc[3] = getc(dvifile); lcx.uc[1] = getc(dvifile); \
+ 367 lcx.uc[0] = getc(dvifile); lcx.uc[2] = 0
+ 368
+ 369 #define three_bytes_s lcx.c[2] = getc(dvifile); lcx.c[1] = getc(dvifile); \
+ 370 lcx.c[0] = getc(dvifile); \
+ 371 lcx.uc[3] = (lcx.c[2] >= 0) ? 0 : 255;
+ 372
+ 373 #define four_bytes lcx.c[3] = getc(dvifile); \
+ 374 lcx.c[2] = getc(dvifile); lcx.c[1] = getc(dvifile); \
+ 375 lcx.c[0] = getc(dvifile);
+ 376
+ 377 /* Knuth's programs like to hardcode fixed maximum sizes for various
+ 378 things, for example, the maximum number of fonts allowed in a DVI file. In
+ 379 general, it is preferable to use the C function malloc to allocate storage
+ 380 as needed. That is what we generally do in this Dvi2ln3, but there are some
+ 381 residues of the Knuthian approach, like MAXTEXFONTS below. By the way, we
+ 382 never attempt to return any storage to the system.
+ 383
+ 384 [[Eventually, it would be better to get rid of MAXTEXFONTS and use a linked
+ 385 list of records instead. There would be no cpu time penalty to using a
+ 386 linked list, because the function set_curf below does a linear search
+ 387 through the font array anyway.]] */
+ 388
+ 389 #define MAXTEXFONTS 100
+ 390
+ 391 struct txf { unsigned char chu[256]; int bc, ec; long int space, design_size,
+ 392 scaled_size; int nchs; };
+ 393
+ 394 GLOBAL struct txf *txfa[MAXTEXFONTS+1];
+ 395
+ 396 /* Font width information needs to be read from TFM files. TFM is a special
+ 397 format defined by TeX. Dvi2ln3 stores each width in a longword. DVItype
+ 398 tries to save space by a two-level width storage method. We just allocate
+ 399 an array of widths for each font with malloc.
+ 400
+ 401 [[We don't check that font checksums match in Dvi2ln3, because there are a
+ 402 lot of slightly obsolete TFMs floating around which would result in a
+ 403 checksum error, but seem to give perfectly reasonable formatted output
+ 404 nonetheless.]] */
+ 405
+ 406 GLOBAL long int *font_width[MAXTEXFONTS+1];
+ 407
+ 408 /* TeX fonts are referred to by their internal numbers, which go from 0 to
+ 409 nf-1. The DVI file refers to them by external numbers, hence the array
+ 410 to_ext used to convert internal numbers to external numbers. Curf is the
+ 411 internal font number of the current font in the DVI file. */
+ 412
+
+DVI2LN3 14-OCT-1985 13:19:13 VAX C V2.0-003 Page 8
+V1.0 14-OCT-1985 13:19:01 USER$4:[TEX.LN03.SOURCES]DVI2LN3.C;40 (1)
+
+ 413 GLOBAL int to_ext[MAXTEXFONTS+1],
+ 414 nf,
+ 415 curf;
+ 416
+ 417 /* In some switch statements, a lot of cases have to be enumerated. We
+ 418 employ this Knuthian macro for that purpose: */
+ 419
+ 420 #define four_cases(_x1) case _x1: case _x1+1: case _x1+2: case _x1+3:
+ 421
+ 422 /* We define a lot of constants corresponding to the DVI operation codes.
+ 423 These are copied from DVItype. */
+ 424
+ 425 #define id_byte 2 /* current version of the dvi format */
+ 426 #define set_char_0 0 /* typeset character 0 and move right */
+ 427 #define set1 128 /* typeset a character and move right */
+ 428 #define set_rule 132 /* typeset a rule and move right */
+ 429 #define put1 133 /* typeset a character */
+ 430 #define put_rule 137 /* typeset a rule */
+ 431 #define nop 138 /* no operation */
+ 432 #define bop 139 /* beginning of page */
+ 433 #define eop 140 /* ending of page */
+ 434 #define push 141 /* save the current positions */
+ 435 #define pop 142 /* restore previous positions */
+ 436 #define right1 143 /* move right */
+ 437 #define w0 147 /* move right by |w| */
+ 438 #define w1 148 /* move right and set |w| */
+ 439 #define x0 152 /* move right by |x| */
+ 440 #define x1 153 /* move right and set |x| */
+ 441 #define down1 157 /* move down */
+ 442 #define y0 161 /* move down by |y| */
+ 443 #define y1 162 /* move down and set |y| */
+ 444 #define z0 166 /* move down by |z| */
+ 445 #define z1 167 /* move down and set |z| */
+ 446 #define fnt_num_0 171 /* set current font to 0 */
+ 447 #define fnt1 235 /* set current font */
+ 448 #define xxx1 239 /* extension to dvi primitives (\special) */
+ 449 #define xxx4 242 /* potentially long extension to dvi primitives */
+ 450 #define fnt_def1 243 /* define the meaning of a font number */
+ 451 #define pre 247 /* preamble */
+ 452 #define post 248 /* postamble beginning */
+ 453 #define post_post 249 /* postamble ending */
+ 454 #define undefined_command 250
+ 455
+ 456 GLOBAL long int mag, num, den;
+ 457 GLOBAL float conv, unmag_conv;
+ 458
+ 459 /* Read_preamble reads the preamble of the dvi file. The comment is thrown
+ 460 away. The format version number is checked. The magnification, numerator,
+ 461 and denominator are remembered in the globals mag, num, den. The float
+ 462 values conv and unmag_conv serve to convert measurements from DVI units to
+ 463 pixels. */
+
+DVI2LN3 14-OCT-1985 13:19:13 VAX C V2.0-003 Page 9
+V1.0 14-OCT-1985 13:19:01 USER$4:[TEX.LN03.SOURCES]DVI2LN3.C;40 (1)
+
+ 464
+ 465 int read_preamble() {
+ 466 1 unsigned int i;
+ 467 1 int j;
+ 468 1
+ 469 1 i = getc(dvifile);
+ 470 1 if (i != pre) return(1);
+ 471 1 i = getc(dvifile);
+ 472 1 if (i != id_byte) return(1);
+ 473 1 four_bytes; num = lcx.l;
+ 474 1 if (num <= 0) return(1);
+ 475 1 four_bytes; den = lcx.l;
+ 476 1 if (den <= 0) return(1);
+ 477 1 four_bytes; mag = lcx.l;
+ 478 1 if (mag <= 0) return(1);
+ 479 1
+ 480 1 unmag_conv = (num/254000.0) * (300.0/den);
+ 481 1 conv = unmag_conv * (mag/1000.0);
+ 482 1
+ 483 1 /* Skip over the comment field. */
+ 484 1
+ 485 1 i = getc(dvifile);
+ 486 1 for (j=0; j<i; j++) getc(dvifile);
+ 487 1 return(0);
+ 488 1 }
+ 489
+ 490 /* The dvi file format requires us to keep track of various quantities,
+ 491 among them the horizontal and vertical positions h and v, and four values
+ 492 referred to simply as x, y, z and w. We also keep pixel-rounded versions
+ 493 of h and v, called hh and vv. */
+ 494
+ 495 GLOBAL long h, v, x, y, z, w;
+ 496 GLOBAL int hh, vv;
+ 497
+ 498 /* The following function, copied from DVItype, reads from the DVI file the
+ 499 first parameter of the current DVI command. In the case of functions whose
+ 500 first parameter is implicit, such as set_char_0 through set_char_127, the
+ 501 implicit parameter is returned. */
+ 502
+ 503 long first_par(o)
+ 504 int o;
+ 505 {
+ 506 1 unsigned int i;
+ 507 1
+ 508 1 if ((o >= set_char_0) && (o < set_char_0+128))
+ 509 1 return(o-set_char_0);
+ 510 1 if ((o >= fnt_num_0) && (o < fnt_num_0+64))
+ 511 1 return(o-fnt_num_0);
+ 512 1 switch (o) {
+ 513 2 case set1:
+ 514 2 case put1:
+
+DVI2LN3 14-OCT-1985 13:19:13 VAX C V2.0-003 Page 10
+V1.0 14-OCT-1985 13:19:01 USER$4:[TEX.LN03.SOURCES]DVI2LN3.C;40 (1)
+
+ 515 2 case fnt1:
+ 516 2 case xxx1:
+ 517 2 case fnt_def1:
+ 518 2 i = getc(dvifile);
+ 519 2 return(i);
+ 520 2 case set1+1:
+ 521 2 case put1+1:
+ 522 2 case fnt1+1:
+ 523 2 case xxx1+1:
+ 524 2 case fnt_def1+1:
+ 525 2 two_bytes_u;
+ 526 2 return(lcx.ul);
+ 527 2 case set1+2:
+ 528 2 case put1+2:
+ 529 2 case fnt1+2:
+ 530 2 case xxx1+2:
+ 531 2 case fnt_def1+2:
+ 532 2 three_bytes_u;
+ 533 2 return(lcx.ul);
+ 534 2 case right1:
+ 535 2 case w1:
+ 536 2 case x1:
+ 537 2 case down1:
+ 538 2 case y1:
+ 539 2 case z1:
+ 540 2 return(getc(dvifile));
+ 541 2 case right1+1:
+ 542 2 case w1+1:
+ 543 2 case x1+1:
+ 544 2 case down1+1:
+ 545 2 case y1+1:
+ 546 2 case z1+1:
+ 547 2 two_bytes_s;
+ 548 2 return(lcx.l);
+ 549 2 case right1+2:
+ 550 2 case w1+2:
+ 551 2 case x1+2:
+ 552 2 case down1+2:
+ 553 2 case y1+2:
+ 554 2 case z1+2:
+ 555 2 three_bytes_s;
+ 556 2 return(lcx.l);
+ 557 2 case set_rule:
+ 558 2 case put_rule:
+ 559 2 case right1+3:
+ 560 2 case w1+3:
+ 561 2 case x1+3:
+ 562 2 case down1+3:
+ 563 2 case y1+3:
+ 564 2 case z1+3:
+ 565 2 case set1+3:
+
+DVI2LN3 14-OCT-1985 13:19:13 VAX C V2.0-003 Page 11
+V1.0 14-OCT-1985 13:19:01 USER$4:[TEX.LN03.SOURCES]DVI2LN3.C;40 (1)
+
+ 566 2 case put1+3:
+ 567 2 case fnt1+3:
+ 568 2 case xxx1+3:
+ 569 2 case fnt_def1+3:
+ 570 2 four_bytes;
+ 571 2 return(lcx.l);
+ 572 2 case w0:
+ 573 2 return(w);
+ 574 2 case x0:
+ 575 2 return(x);
+ 576 2 case y0:
+ 577 2 return(y);
+ 578 2 case z0:
+ 579 2 return(z);
+ 580 2 default:
+ 581 2 return(0);
+ 582 2 }
+ 583 1 }
+ 584
+ 585 /* Pass1 reads from the DVI file until the starting page condition is met.
+ 586 Return 1 if something goes wrong, or if the DVI file comes to an end. This
+ 587 resembles skip_pages below. */
+ 588
+ 589 int pass1() {
+ 590 1
+ 591 1 unsigned int k;
+ 592 1 long int p;
+ 593 1 int i;
+ 594 1 char startp;
+ 595 1
+ 596 1 if (read_preamble() != 0) {
+ 597 2 printf(bad_DVI_message);
+ 598 2 return(1);
+ 599 2 }
+ 600 1
+ 601 1 for (;;) {
+ 602 2 if (feof(dvifile)) {
+ 603 3 printf(bad_DVI_message);
+ 604 3 return(1);
+ 605 3 }
+ 606 2 k = getc(dvifile);
+ 607 2 if (k == post) return(0);
+ 608 2 p = first_par(k);
+ 609 2 if (k >= set_char_0 && k < set_char_0+128) k = set1;
+ 610 2 if (k >= fnt_num_0 && k < fnt_num_0+64) k = fnt1;
+ 611 2
+ 612 2 switch (k) {
+ 613 3 case bop:
+ 614 3 startp = 1;
+ 615 3 for (i=0; i<10; i++) {
+ 616 4 four_bytes;
+
+DVI2LN3 14-OCT-1985 13:19:13 VAX C V2.0-003 Page 12
+V1.0 14-OCT-1985 13:19:01 USER$4:[TEX.LN03.SOURCES]DVI2LN3.C;40 (1)
+
+ 617 4 if (i < how_many_counts && use_count[i] &&
+ 618 4 lcx.l != start_page[i]) startp = 0;
+ 619 4 }
+ 620 3 four_bytes;
+ 621 3 if (startp != 0) num_pages = 1;
+ 622 3 else if (num_pages > 0) {
+ 623 4 num_pages++;
+ 624 4 if (num_pages > max_pages) return(0);
+ 625 4 }
+ 626 3 break;
+ 627 3 case set_rule:
+ 628 3 case put_rule:
+ 629 3 four_bytes;
+ 630 3 break;
+ 631 3 four_cases(fnt_def1)
+ 632 3 i = define_font(p);
+ 633 3 if (i != 0) return(1);
+ 634 3 break;
+ 635 3 four_cases(fnt1)
+ 636 3 if (num_pages > 0) set_curf(p);
+ 637 3 break;
+ 638 3 four_cases(set1)
+ 639 3 four_cases(put1)
+ 640 3 if (num_pages > 0)
+ 641 3 txfa[curf] -> chu[p] = 1;
+ 642 3 break;
+ 643 3 four_cases(xxx1)
+ 644 3 for (; p>0; p--) getc(dvifile);
+ 645 3 break;
+ 646 3 default:
+ 647 3 break;
+ 648 3 }
+ 649 2 }
+ 650 1 return(0);
+ 651 1 }
+ 652
+ 653 #define leftfirst 33
+ 654 #define rightfirst 161
+ 655 #define leftlast 126
+ 656 #define rightlast 254
+ 657
+ 658 /* The define of maxnfonts below is based on a belief, perhaps
+ 659 superstitious, that there is a limit of 31 downline-loaded fonts in the
+ 660 LN03. For us an nfont is two LN03 fonts, hence the following definition. */
+ 661
+ 662 #define maxnfonts 16
+ 663
+ 664 /* Txf is a record structure describing a TeX font. Txfa is an array of txf
+ 665 records. Txf2lnf describes the mapping between TeX fonts and pairs of LN03
+ 666 fonts. Because the constructed LN03 font load has just the glyphs that are
+ 667 needed, we can often cram more than one TeX font into a pair of LN03 fonts.
+
+DVI2LN3 14-OCT-1985 13:19:13 VAX C V2.0-003 Page 13
+V1.0 14-OCT-1985 13:19:01 USER$4:[TEX.LN03.SOURCES]DVI2LN3.C;40 (1)
+
+ 668
+ 669 Why a pair of fonts? Because LN03 fonts are allowed to hold 94 glyphs only.
+ 670 They come in two flavors, "left" which answer to character codes 33 to 126,
+ 671 and "right" which answer to codes 161 to 254. LN03Topp assigns each TeX
+ 672 font to one "lnfno", where each lnfno denotes a pair of LN03 fonts, one
+ 673 left, one right. */
+ 674
+ 675 GLOBAL int txf2lnf[MAXTEXFONTS];
+ 676
+ 677 /* Maxfontnos reflects the fact that all LN03 fonts must be denoted by
+ 678 a number from 10 to 19. */
+ 679
+ 680 #define maxfontnos 9
+ 681
+ 682 GLOBAL int lastch[maxnfonts];
+ 683 GLOBAL unsigned char chw[maxnfonts][256];
+ 684 GLOBAL char fname[maxnfonts][32];
+ 685
+ 686 /* The LN03 font-denoting numbers 10-19 have to be allocated among the
+ 687 fonts. The useno array keeps track of which number a font is allowed to
+ 688 use, -1 if none is currently allocated. The whouses array says which font
+ 689 is using a number. */
+ 690
+ 691 GLOBAL int useno[maxnfonts],whouses[maxfontnos];
+ 692
+ 693 /* Font_name points to strings containing font names, which are created
+ 694 with malloc as needed. */
+ 695
+ 696 GLOBAL char *font_name[MAXTEXFONTS+1];
+ 697
+ 698 GLOBAL int maxrmar,maxbmar;
+ 699
+ 700 #define max(x,y) (((x)>(y))?(x):(y))
+ 701 #define min(x,y) (((x)<(y))?(x):(y))
+ 702
+ 703 /* Make_font_load calls on other procedures to generate the LN03 font load.
+ 704 */
+ 705
+ 706 int make_font_load() {
+ 707 1
+ 708 1 int i,j,jj,k,l,fno,maxfno,chsize;
+ 709 1 long int totsize;
+ 710 1 int lnfcnt,txfcnt,the_txf,txf_size,lnfleft;
+ 711 1 int txford[MAXTEXFONTS];
+ 712 1 char cnt[3];
+ 713 1
+ 714 1 totsize = 0;
+ 715 1 chsize = 0;
+ 716 1 curf = 0;
+ 717 1 for (i=0; i<maxnfonts; i++)
+ 718 1 for (j=0; j<256; j++) chw[i][j] = 0;
+
+DVI2LN3 14-OCT-1985 13:19:13 VAX C V2.0-003 Page 14
+V1.0 14-OCT-1985 13:19:01 USER$4:[TEX.LN03.SOURCES]DVI2LN3.C;40 (1)
+
+ 719 1
+ 720 1 for (jj=0; jj<MAXTEXFONTS; jj++) txf2lnf[jj] = -1;
+ 721 1
+ 722 1 /* Fill the fname strings with different valid LN03 font names. */
+ 723 1
+ 724 1 for (i=0; i<maxnfonts; i++)
+ 725 1 strcpy(fname[i],"U000000002SK00GG0001UZZZZ02F000");
+ 726 1 for (jj=1; jj<maxnfonts; jj++) {
+ 727 2 sprintf(cnt,"%02d",jj);
+ 728 2 strncpy(&(fname[jj][5]),cnt,2);
+ 729 2 }
+ 730 1
+ 731 1 /* The margins are set to values appropriate for American 8 1/2 by 11
+ 732 1 paper. It is not clear if this needs to be changed for European A4 paper.
+ 733 1 Not changing it might deprive Europeans of access to the bottom 1.5cm of
+ 734 1 their paper. */
+ 735 1
+ 736 1 maxrmar = 2550;
+ 737 1 maxbmar = 3300;
+ 738 1
+ 739 1 /* In the following, esc[?27h means "advance the carriage by the character
+ 740 1 width when you set a character", esc[11h and esc[7 I together mean to
+ 741 1 interpret all dimensions in escape sequences as pixel units; esc[?52h means
+ 742 1 our origin of coordinates is the upper left edge of the paper; esc[%dt
+ 743 1 means the "maximum length" of the paper is maxbmar pixels. */
+ 744 1
+ 745 1 fprintf(outfile,"\033c\033[?27h\033[11h\033[7 I\033[?52h\033[%dt\n",
+ 746 1 maxbmar);
+ 747 1
+ 748 1 for (i=0; i<maxnfonts; i++) useno[i] = -1;
+ 749 1 for (i=0; i<maxfontnos; i++) whouses[i] = -1;
+ 750 1 maxfno = -1;
+ 751 1
+ 752 1 /* Write font loading escape sequence onto outf. [[It may be desirable to
+ 753 1 make this escape sequence clear all dowloaded fonts from RAM.]] */
+ 754 1
+ 755 1 fprintf(outfile,"\033P0;1;1y");
+ 756 1
+ 757 1 /* Count how many glyphs each font requires. */
+ 758 1
+ 759 1 for (fno=0; fno<nf; fno++) {
+ 760 2
+ 761 2 txfa[fno] -> nchs = 0;
+ 762 2 for(i=0; i<256; i++)
+ 763 2 if (txfa[fno] -> chu[i] != 0) txfa[fno] -> nchs++;
+ 764 2
+ 765 2 if (txfa[fno] -> nchs > 188) goto need_empty_slots;
+ 766 2 chsize += txfa[fno] -> nchs;
+ 767 2 }
+ 768 1 printf("\nFont load to contain %d glyphs.",chsize);
+ 769 1
+
+DVI2LN3 14-OCT-1985 13:19:13 VAX C V2.0-003 Page 15
+V1.0 14-OCT-1985 13:19:01 USER$4:[TEX.LN03.SOURCES]DVI2LN3.C;40 (1)
+
+ 770 1
+ 771 1 /* Now we have to allocate TeX fonts to LN03 fonts pairs and perform the
+ 772 1 actual load. The goal is to use as few slots as possible, where an LN03
+ 773 1 font pair with <= 94 glyphs is one slot, and a font pair with > 94 but <=
+ 774 1 188 glyphs is two slots.
+ 775 1
+ 776 1 As in the LN01 case, the allocation problem seems to be some sort of hard
+ 777 1 bin packing problem. (Proof of NP-hardness, anyone?) So we use a best fit
+ 778 1 heuristic:
+ 779 1
+ 780 1 1. Find the unassigned largest TeX font. If none, exit, we're done.
+ 781 1
+ 782 1 2. Allocate an LN03 font pair for that TeX font and put the TeX
+ 783 1 font into it.
+ 784 1
+ 785 1 3. Find the largest remaining TeX font that fits in what is left of
+ 786 1 that LN03 font pair.
+ 787 1
+ 788 1 3.1. if none exists, go to 1.
+ 789 1 3.2. if one exists, put it in the font pair and go back to 3.
+ 790 1
+ 791 1 The txford array contains the TeX font numbers in the order that they are
+ 792 1 assigned. Txfcnt keeps track of how many TeX fonts have been assigned so
+ 793 1 far. */
+ 794 1
+ 795 1 lnfcnt = 0;
+ 796 1 txfcnt = 0;
+ 797 1 for (i=0; i<MAXTEXFONTS; i++) txford[i] = -1;
+ 798 1
+ 799 1 while (1) {
+ 800 2
+ 801 2 /* Find largest unassigned TeX font */
+ 802 2
+ 803 2 lnfleft = rightlast-rightfirst+1+leftlast-leftfirst+1;
+ 804 2 txf_size = -1;
+ 805 2 for (j = 0; j < MAXTEXFONTS; j++) {
+ 806 3 if (txfa[j] != 0 && txf2lnf[j] == -1
+ 807 3 && txfa[j] -> nchs > txf_size) {
+ 808 4 txf_size = txfa[j] -> nchs;
+ 809 4 the_txf = j;
+ 810 4 }
+ 811 3 }
+ 812 2 if (txf_size <= 0) goto assignment_done;
+ 813 2 if (lnfcnt > maxnfonts) goto too_complex;
+ 814 2 if (txf_size > lnfleft) goto need_empty_slots;
+ 815 2
+ 816 2 /* Now allocate new LN03 font pair and put the current TeX font into it */
+ 817 2
+ 818 2 txf2lnf[the_txf] = lnfcnt;
+ 819 2 txford[txfcnt] = the_txf;
+ 820 2 txfcnt++;
+
+DVI2LN3 14-OCT-1985 13:19:13 VAX C V2.0-003 Page 16
+V1.0 14-OCT-1985 13:19:01 USER$4:[TEX.LN03.SOURCES]DVI2LN3.C;40 (1)
+
+ 821 2 k = leftfirst-1;
+ 822 2 for (j = 0; j <= 255; j++) {
+ 823 3 if (txfa[the_txf] -> chu[j] != 0) {
+ 824 4 k++;
+ 825 4 if (k == leftlast+1) k = rightfirst;
+ 826 4 lnfleft--;
+ 827 4 txfa[the_txf] -> chu[j] = k;
+ 828 4 }
+ 829 3 }
+ 830 2 lastch[lnfcnt] = k;
+ 831 2
+ 832 2 /* Now try to fill the remaining part of the LN03 font pair using other TeX
+ 833 2 fonts */
+ 834 2
+ 835 2 while (1) {
+ 836 3
+ 837 3 txf_size = -1;
+ 838 3 for (j = 0; j < MAXTEXFONTS; j++) {
+ 839 4 if (txfa[j] != 0 && txf2lnf[j] == -1
+ 840 4 && txfa[j] -> nchs > txf_size
+ 841 4 && txfa[j] -> nchs <= lnfleft) {
+ 842 5 txf_size = txfa[j] -> nchs;
+ 843 5 the_txf = j;
+ 844 5 }
+ 845 4 }
+ 846 3 if (txf_size <= 0) break;
+ 847 3
+ 848 3 txf2lnf[the_txf] = lnfcnt;
+ 849 3 txford[txfcnt] = the_txf;
+ 850 3 txfcnt++;
+ 851 3 k = lastch[lnfcnt];
+ 852 3 for (j=0; j<=255; j++) {
+ 853 4 if (txfa[the_txf] -> chu[j] != 0) {
+ 854 5 k++;
+ 855 5 lnfleft--;
+ 856 5 if (k == leftlast+1) k = rightfirst;
+ 857 5 txfa[the_txf] -> chu[j] = k;
+ 858 5 }
+ 859 4 }
+ 860 3 lastch[lnfcnt] = k;
+ 861 3 }
+ 862 2
+ 863 2 lnfcnt++;
+ 864 2 }
+ 865 1
+ 866 1 assignment_done:
+ 867 1
+ 868 1 /* At this point the array txf2lnf is properly initialized, as are lastch
+ 869 1 and txford. It remains to actually generate the desired font load. This has
+ 870 1 to be done carefully, since the function add_txf_to_lnf only supports
+ 871 1 adding glyphs to an LN03 font pair in ascending order of character code. */
+
+DVI2LN3 14-OCT-1985 13:19:13 VAX C V2.0-003 Page 17
+V1.0 14-OCT-1985 13:19:01 USER$4:[TEX.LN03.SOURCES]DVI2LN3.C;40 (1)
+
+ 872 1
+ 873 1 for (j=0; j<txfcnt; j++) {
+ 874 2 k = txford[j];
+ 875 2 if (j != 0 && txf2lnf[k] != txf2lnf[txford[j-1]])
+ 876 2 fprintf(outfile,",\n");
+ 877 2 totsize += add_txf_to_lnf(txf2lnf[k],k);
+ 878 2 }
+ 879 1
+ 880 1 /* [[At this point we ought to add code that writes a message saying how
+ 881 1 much font RAM the load will occupy. But there is no documentation for
+ 882 1 determining that! So, we make the following compromise:]] */
+ 883 1
+ 884 1 printf("\n Approximate size of font load: %ld bytes",totsize);
+ 885 1
+ 886 1 /* [[We may want to insert a few \n's in the following to keep the line
+ 887 1 from getting too long.]] */
+ 888 1
+ 889 1 fprintf(outfile,"\n;Dvi2ln3 1 font load\033\\");
+ 890 1 fprintf(outfile,"\033[1;%ds\033[%dt\033[1;%dr",maxrmar,maxbmar,maxbmar);
+ 891 1 for (j=0; j <= min(maxfontnos,lnfcnt-1); j++) {
+ 892 2 useno[j] = j;
+ 893 2 whouses[j] = j;
+ 894 2 k = fname[j][16];
+ 895 2 fname[j][16] = '\0';
+ 896 2 fprintf(outfile,"\033P1;1%d}%s\033\\",j,fname[j]);
+ 897 2 fname[j][16] = k;
+ 898 2 }
+ 899 1 fprintf(outfile,"\033[10m");
+ 900 1
+ 901 1 return(0);
+ 902 1
+ 903 1 too_complex:
+ 904 1 printf("\n Can't construct a font load:");
+ 905 1 printf("\n Dvi file uses too many glyphs from too many different fonts.");
+ 906 1 return(1);
+ 907 1
+ 908 1 /* [[We need to determine what the real limit is on the number of LN03
+ 909 1 fonts, and refine the test to detect if it is being exceeded. Fortunately,
+ 910 1 only a very complex DVI file could exceed the limit.]] */
+ 911 1
+ 912 1 need_empty_slots:
+ 913 1 printf("\nFont %s uses > 188 characters. Can't handle that.",
+ 914 1 font_name[fno]);
+ 915 1 return(1);
+ 916 1
+ 917 1 /* [[The error message above should be fixed to specify the magnification
+ 918 1 of the font also.]] */
+ 919 1
+ 920 1 }
+ 921
+ 922 /* The lines in the LN3 file are limited to lengths of about 100 bytes. We
+
+DVI2LN3 14-OCT-1985 13:19:13 VAX C V2.0-003 Page 18
+V1.0 14-OCT-1985 13:19:01 USER$4:[TEX.LN03.SOURCES]DVI2LN3.C;40 (1)
+
+ 923 keep track of how many bytes are written so far in the global lnhp. The
+ 924 accounting is conservative, so e.g. each pixel position counts as 4 bytes
+ 925 even though it might be shorter. [[One could easily increase 100 to 200. It
+ 926 is not clear what problems are provoked by going over, say, 256.]]
+ 927
+ 928 Vpset keeps track of whether the vertical position needs to be output to
+ 929 the LN03 file before setting any more characters. Hh_old keeps track of the
+ 930 horizontal position which LN03 thinks it's at. */
+ 931
+ 932 GLOBAL int ln3p,vpset,hh_old;
+ 933
+ 934 #define inc_ln3p(x) ln3p += x; if (ln3p > 100) \
+ 935 { ln3p = 0; vpset = 0; hh_old = 30000; }
+ 936
+ 937 /* [[In the above macro, hh_old is set to 30000 to mean "a very large
+ 938 number" (the maximum valid hh for an LN03 is 2550), so as to force the code
+ 939 below to re-output the true hh. What are the implications of this kludge?
+ 940 Would it not be more reasonable to have instead an hhset variable?]] */
+ 941
+ 942 /* A stack of hvxyzw values is kept; the stack pointer is called s.
+ 943 [[Again, it would be better to make this stack a linked list.]] */
+ 944
+ 945 #define STACKSIZE 100
+ 946
+ 947 GLOBAL long hstack[STACKSIZE], vstack[STACKSIZE], xstack[STACKSIZE],
+ 948 ystack[STACKSIZE], zstack[STACKSIZE], wstack[STACKSIZE];
+ 949 GLOBAL int hhstack[STACKSIZE], vvstack[STACKSIZE];
+ 950 GLOBAL int s;
+ 951
+ 952 /* DVI files specify distances in units of 2^-16 points. When translating
+ 953 to a device-specific format, it is necessary to round the DVI distances to
+ 954 pixel units. This is done by means of the pixel_round macro.
+ 955
+ 956 However, rather than using this macro in the straightforward way, rounding
+ 957 is often performed by more elaborate techniques, which we call "Stanford
+ 958 rules" (after John Le Carre's "Moscow rules"). These rules make use of a
+ 959 parameter MAX_DRIFT, which is roughly the maximum number of pixels that
+ 960 things are allowed to deviate from straightforward rounding. */
+ 961
+ 962 #define pixel_round(x) ((int) ((x<0) ? \
+ 963 (conv*(x)-0.5) : (conv*(x)+0.5)))
+ 964
+ 965 #define MAX_DRIFT 2
+ 966
+ 967 /* Pass2 reads the dvi file and interprets the commands in it, usually by
+ 968 calling other routines. The interpretation generally consists of writing
+ 969 something into the ln3 file, updating the current fonts and positions, and
+ 970 possibly updating the stack. */
+ 971
+ 972 int pass2()
+ 973 {
+
+DVI2LN3 14-OCT-1985 13:19:13 VAX C V2.0-003 Page 19
+V1.0 14-OCT-1985 13:19:01 USER$4:[TEX.LN03.SOURCES]DVI2LN3.C;40 (1)
+
+ 974 1 int i,j;
+ 975 1 long int p;
+ 976 1 unsigned int k;
+ 977 1
+ 978 1 if (read_preamble() != 0) {
+ 979 2 printf(bad_DVI_message);
+ 980 2 return(1);
+ 981 2 }
+ 982 1
+ 983 1 curf = 0;
+ 984 1 ln3p = 0;
+ 985 1 s = 0;
+ 986 1 vpset = 0;
+ 987 1 hh_old = 30000;
+ 988 1
+ 989 1 /* Skip pages until the desired starting page is reached. A nonzero value
+ 990 1 is returned if the starting page is never encountered. */
+ 991 1
+ 992 1 if (skip_pages() != 0) return(0);
+ 993 1
+ 994 1 for (;;) {
+ 995 2 if feof(dvifile) {
+ 996 3 printf(bad_DVI_message);
+ 997 3 return(1); }
+ 998 2 k = getc(dvifile);
+ 999 2 if (k == post) return(0);
+ 1000 2 if (k >= undefined_command) {
+ 1001 3 printf(bad_DVI_message);
+ 1002 3 return(1); }
+ 1003 2
+ 1004 2 p = first_par(k);
+ 1005 2
+ 1006 2 /* If the opcode is an "implicit parameter" opcode, either set_char_n and
+ 1007 2 fnt_num_n, we change it to an explicit parameter opcode to make the case
+ 1008 2 jumps more reasonable. */
+ 1009 2
+ 1010 2 if (k >= set_char_0 && k < set_char_0+128) k = set1;
+ 1011 2 if (k >= fnt_num_0 && k < fnt_num_0+64) k = fnt1;
+ 1012 2
+ 1013 2 j = do_command(k,p);
+ 1014 2 if (j == 2) return(0); /* done with the required number of pages */
+ 1015 2 else if (j == 1) return(1); /* error encountered, stop */
+ 1016 2
+ 1017 2 }
+ 1018 1 }
+ 1019
+ 1020 /* Read from the DVI file until the starting page condition is met. Return
+ 1021 1 if something goes wrong, or if the DVI file comes to an end. This
+ 1022 function is copied quite closely from DVItype. */
+ 1023
+ 1024 int skip_pages() {
+
+DVI2LN3 14-OCT-1985 13:19:13 VAX C V2.0-003 Page 20
+V1.0 14-OCT-1985 13:19:01 USER$4:[TEX.LN03.SOURCES]DVI2LN3.C;40 (1)
+
+ 1025 1
+ 1026 1 unsigned int k;
+ 1027 1 int i;
+ 1028 1 long p,first_page;
+ 1029 1 char startp;
+ 1030 1
+ 1031 1 for (;;) {
+ 1032 2 if (feof(dvifile)) return(1);
+ 1033 2 k = getc(dvifile);
+ 1034 2 if (k == post) return(1);
+ 1035 2 p = first_par(k);
+ 1036 2 if (k >= set_char_0 && k < set_char_0+128) k = set1;
+ 1037 2 if (k >= fnt_num_0 && k < fnt_num_0+64) k = fnt1;
+ 1038 2
+ 1039 2 switch (k) {
+ 1040 3 case bop:
+ 1041 3 startp = 1;
+ 1042 3 for (i=0; i<10; i++) {
+ 1043 4 four_bytes;
+ 1044 4 if (i == 0) first_page = lcx.l;
+ 1045 4 if (i < how_many_counts && use_count[i] &&
+ 1046 4 lcx.l != start_page[i]) startp = 0;
+ 1047 4 }
+ 1048 3 four_bytes;
+ 1049 3 if (startp != 0) {
+ 1050 4 v = 0; vv = 0; h = 0; hh = 0;
+ 1051 4 printf("\n [%ld]",first_page);
+ 1052 4 num_pages = 1; return(0); }
+ 1053 3 break;
+ 1054 3 case set_rule:
+ 1055 3 case put_rule:
+ 1056 3 four_bytes;
+ 1057 3 break;
+ 1058 3 four_cases(fnt_def1)
+ 1059 3 i = define_font(p);
+ 1060 3 if (i != 0) return(1);
+ 1061 3 break;
+ 1062 3 four_cases(xxx1)
+ 1063 3 for (; p>0; p--) getc(dvifile);
+ 1064 3 break;
+ 1065 3 default:
+ 1066 3 break;
+ 1067 3 }
+ 1068 2 }
+ 1069 1 return(0);
+ 1070 1 }
+ 1071
+ 1072 /* Do_command performs the DVI command of code k, assuming the "first
+ 1073 parameter" is p. It is assumed that k is not one of set_char0 through
+ 1074 set_char127. */
+ 1075
+
+DVI2LN3 14-OCT-1985 13:19:13 VAX C V2.0-003 Page 21
+V1.0 14-OCT-1985 13:19:01 USER$4:[TEX.LN03.SOURCES]DVI2LN3.C;40 (1)
+
+ 1076 int do_command(k,p)
+ 1077 int k;
+ 1078 long p;
+ 1079 {
+ 1080 1 int i,j,l,lnf;
+ 1081 1
+ 1082 1 switch (k) {
+ 1083 2 four_cases(fnt_def1)
+ 1084 2 define_font_pass2();
+ 1085 2 break;
+ 1086 2
+ 1087 2 /* [[In processing the put and set DVI commands, no check is made that the
+ 1088 2 character being set actually exists in the font. This can lead to messy
+ 1089 2 errors, like access violations or garbage values when one tries to find
+ 1090 2 that character's width. Neither is any check made that the horizontal and
+ 1091 2 vertical positions fall within the page.]] */
+ 1092 2
+ 1093 2 four_cases(put1)
+ 1094 2 four_cases(set1)
+ 1095 2 if (!vpset) {
+ 1096 3 fprintf(outfile,"\n\033[%dd\033[%d`",vv+voff,hh+hoff);
+ 1097 3 ln3p = 16;
+ 1098 3 vpset = 1;
+ 1099 3 hh_old = hh;
+ 1100 3 }
+ 1101 2 if (hh_old != hh) {
+ 1102 3 if (hh > hh_old) fprintf(outfile,"\033[%da",hh-hh_old);
+ 1103 3 else fprintf(outfile,"\033[%d`",hh+hoff);
+ 1104 3 ln3p += 7;
+ 1105 3 }
+ 1106 2 putc(txfa[curf] -> chu[p],outfile);
+ 1107 2 inc_ln3p(1);
+ 1108 2 if (k >= put1) {
+ 1109 3 hh_old = hh;
+ 1110 3 break;
+ 1111 3 }
+ 1112 2 h += font_width[curf][p];
+ 1113 2
+ 1114 2 /* In rounding h to generate the pixel-position hh, Stanford rules (see
+ 1115 2 above) come into play. We set the new hh (horizontal position in pixels) to
+ 1116 2 the value obtained by adding the pixel width of the character being set to
+ 1117 2 the current position. We then correct this value so that it does not exceed
+ 1118 2 the rounded version of the true position by more than MAX_DRIFT pixels.
+ 1119 2
+ 1120 2 Note that if we did not apply Stanford rules here, or equivalently if we
+ 1121 2 set MAX_DRIFT to zero, many more set-X-position commands would appear in
+ 1122 2 the output. */
+ 1123 2
+ 1124 2 hh += chw[txf2lnf[curf]][txfa[curf] -> chu[p]];
+ 1125 2 hh_old = hh;
+ 1126 2 l = pixel_round(h);
+
+DVI2LN3 14-OCT-1985 13:19:13 VAX C V2.0-003 Page 22
+V1.0 14-OCT-1985 13:19:01 USER$4:[TEX.LN03.SOURCES]DVI2LN3.C;40 (1)
+
+ 1127 2 if (hh-l > MAX_DRIFT) hh = l+MAX_DRIFT;
+ 1128 2 else if (l-hh > MAX_DRIFT) hh = l-MAX_DRIFT;
+ 1129 2 break;
+ 1130 2
+ 1131 2 four_cases(fnt1)
+ 1132 2 set_curf(p);
+ 1133 2 lnf = txf2lnf[curf];
+ 1134 2 if (useno[lnf] == -1) {
+ 1135 3 useno[whouses[maxfontnos]] = -1;
+ 1136 3 useno[lnf] = maxfontnos;
+ 1137 3 whouses[maxfontnos] = lnf;
+ 1138 3 fprintf(outfile,"\033P1;1%d}%16s\033\\",maxfontnos,
+ 1139 3 fname[lnf]);
+ 1140 3 inc_ln3p(26);
+ 1141 3 }
+ 1142 2 fprintf(outfile,"\033[1%dm",useno[lnf]);
+ 1143 2 inc_ln3p(5);
+ 1144 2 break;
+ 1145 2
+ 1146 2 case set_rule:
+ 1147 2 case put_rule:
+ 1148 2
+ 1149 2 /* When converting rule dimensions to pixel dimensions, we do not follow
+ 1150 2 Stanford rules. Rather, we just round the true positions to obtain the
+ 1151 2 pixel positions. This avoids unsightly gaps between rules. [[It should not
+ 1152 2 cause much of a problem with typical rule applications (ruled tables,
+ 1153 2 fraction bars)...but perhaps with large delimiters there might be some
+ 1154 2 difficulty. This needs more thought...]] */
+ 1155 2
+ 1156 2 four_bytes;
+ 1157 2 if (p >= 0 && lcx.l >= 0)
+ 1158 2 do_rule(pixel_round(h),
+ 1159 2 pixel_round(v-p),pixel_round(h+lcx.l),
+ 1160 2 pixel_round(v));
+ 1161 2 if (k == set_rule) {
+ 1162 3 h += lcx.l;
+ 1163 3 hh = pixel_round(h);
+ 1164 3 }
+ 1165 2 break;
+ 1166 2
+ 1167 2 case push:
+ 1168 2 s++;
+ 1169 2 if (s == STACKSIZE) {
+ 1170 3 printf("\n Stack too deep for Dvi2ln3");
+ 1171 3 return(1);
+ 1172 3 }
+ 1173 2 xstack[s] = x;
+ 1174 2 ystack[s] = y;
+ 1175 2 vstack[s] = v;
+ 1176 2 hstack[s] = h;
+ 1177 2 vvstack[s] = vv;
+
+DVI2LN3 14-OCT-1985 13:19:13 VAX C V2.0-003 Page 23
+V1.0 14-OCT-1985 13:19:01 USER$4:[TEX.LN03.SOURCES]DVI2LN3.C;40 (1)
+
+ 1178 2 hhstack[s] = hh;
+ 1179 2 wstack[s] = w;
+ 1180 2 zstack[s] = z;
+ 1181 2 break;
+ 1182 2
+ 1183 2 case pop:
+ 1184 2 if (s == 0) {
+ 1185 3 printf(bad_DVI_message);
+ 1186 3 return(1);
+ 1187 3 }
+ 1188 2 if (vv != vvstack[s]) vpset = 0;
+ 1189 2 x = xstack[s];
+ 1190 2 y = ystack[s];
+ 1191 2 v = vstack[s];
+ 1192 2 h = hstack[s];
+ 1193 2 vv = vvstack[s];
+ 1194 2 hh = hhstack[s];
+ 1195 2 w = wstack[s];
+ 1196 2 z = zstack[s];
+ 1197 2 s--;
+ 1198 2 break;
+ 1199 2
+ 1200 2 /* Right now there are no \special's defined, so when we get a \special, we
+ 1201 2 just skip over it. */
+ 1202 2
+ 1203 2 four_cases(xxx1)
+ 1204 2 for (; p != 0; p--) getc(dvifile);
+ 1205 2 break;
+ 1206 2
+ 1207 2 case bop:
+ 1208 2
+ 1209 2 /* If we've done the required number of pages, we'll skip the rest of the
+ 1210 2 DVI file. If not, type the first parameter of bop on the user's terminal
+ 1211 2 the way TeX does, to give an indication of progress. */
+ 1212 2
+ 1213 2 if (num_pages == max_pages) return(2);
+ 1214 2 v = 0; vv = 0; h = 0; hh = 0;
+ 1215 2 vpset = 0; hh_old = 100000;
+ 1216 2 four_bytes;
+ 1217 2 if (num_pages%12 == 0) printf("\n");
+ 1218 2 printf(" [%ld]",lcx.ul);
+ 1219 2 num_pages++;
+ 1220 2 for (i = 0; i<40; i++) getc(dvifile);
+ 1221 2 break;
+ 1222 2
+ 1223 2 case eop:
+ 1224 2 fprintf(outfile,"\n\f");
+ 1225 2 ln3p = 0;
+ 1226 2 break;
+ 1227 2
+ 1228 2 /* Now we have to consider the cases for pure motion. */
+
+DVI2LN3 14-OCT-1985 13:19:13 VAX C V2.0-003 Page 24
+V1.0 14-OCT-1985 13:19:01 USER$4:[TEX.LN03.SOURCES]DVI2LN3.C;40 (1)
+
+ 1229 2
+ 1230 2 four_cases(right1)
+ 1231 2 set_h(h+p);
+ 1232 2 break;
+ 1233 2 four_cases(x1)
+ 1234 2 x = p;
+ 1235 2 case x0:
+ 1236 2 set_h(h+x);
+ 1237 2 break;
+ 1238 2 four_cases(y1)
+ 1239 2 y = p;
+ 1240 2 case y0:
+ 1241 2 set_v(v+y);
+ 1242 2 break;
+ 1243 2 four_cases(w1)
+ 1244 2 w = p;
+ 1245 2 case w0:
+ 1246 2 set_h(h+w);
+ 1247 2 break;
+ 1248 2 four_cases(z1)
+ 1249 2 z = p;
+ 1250 2 case z0:
+ 1251 2 set_v(v+z);
+ 1252 2 break;
+ 1253 2 four_cases(down1)
+ 1254 2 set_v(v+p);
+ 1255 2 break;
+ 1256 2
+ 1257 2 }
+ 1258 1 return(0);
+ 1259 1 }
+ 1260
+ 1261 /* Set_curf sets the current font to external number p. Note that the
+ 1262 current font is maintained as an internal font number. */
+ 1263
+ 1264 int set_curf(p)
+ 1265 int p;
+ 1266 {
+ 1267 1 to_ext[nf] = p;
+ 1268 1 curf = 0;
+ 1269 1 while (to_ext[curf] != p) { curf++; }
+ 1270 1 }
+ 1271
+ 1272 /* Define_font processes a font definition from the DVI file. The TFM file
+ 1273 for the font is read at this point from the directory TEX$FONTS. */
+ 1274
+ 1275 int define_font(e)
+ 1276 int e;
+ 1277 {
+ 1278 1 int i;
+ 1279 1 unsigned char p,n;
+
+DVI2LN3 14-OCT-1985 13:19:13 VAX C V2.0-003 Page 25
+V1.0 14-OCT-1985 13:19:01 USER$4:[TEX.LN03.SOURCES]DVI2LN3.C;40 (1)
+
+ 1280 1 if (e == MAXTEXFONTS) { printf("\n Too many fonts for Dvi2ln3");
+ 1281 2 return(1); }
+ 1282 1 txfa[nf] = malloc(sizeof(struct txf));
+ 1283 1 to_ext[nf] = e;
+ 1284 1 four_bytes;
+ 1285 1 four_bytes;
+ 1286 1 txfa[nf] -> scaled_size = lcx.l;
+ 1287 1 four_bytes;
+ 1288 1 txfa[nf] -> design_size = lcx.l;
+ 1289 1 for (i=0; i<256; i++) txfa[nf] -> chu[i] = '\0';
+ 1290 1 p = getc(dvifile); n = getc(dvifile);
+ 1291 1 font_name[nf] = malloc(p+n+1);
+ 1292 1 for (i=0; i<p+n; i++) { font_name[nf][i] = getc(dvifile); }
+ 1293 1 font_name[nf][p+n] = '\0';
+ 1294 1
+ 1295 1 if (txfa[nf] -> scaled_size <= 0 || txfa[nf] -> scaled_size >=
+ 1296 1 8*8*8*8*8*8*8*8*8) {
+ 1297 2 printf("\n Font %s has a bad scaled size",font_name[nf]);
+ 1298 2 return(1);
+ 1299 2 }
+ 1300 1 if (txfa[nf] -> design_size <= 0 || txfa[nf] -> design_size >=
+ 1301 1 8*8*8*8*8*8*8*8*8) {
+ 1302 2 printf("\n Font %s has a bad design size",font_name[nf]);
+ 1303 2 return(1);
+ 1304 2 }
+ 1305 1
+ 1306 1 /* We follow DVItype and compute for each font a "space" parameter which is
+ 1307 1 one-sixth of the scaled design size. This parameter is used in rounding the
+ 1308 1 horizontal position to pixels according to "Stanford rules." See the
+ 1309 1 function set_h below. */
+ 1310 1
+ 1311 1 txfa[nf] -> space = txfa[nf] -> scaled_size/6;
+ 1312 1
+ 1313 1 i = read_tfm_file();
+ 1314 1 if (i != 0) return(i);
+ 1315 1 nf++;
+ 1316 1 return(0);
+ 1317 1
+ 1318 1 }
+ 1319
+ 1320 /* TFM files, like the DVI file, are read with getc, foolish as that may
+ 1321 seem. We use the same overlays that are used for merging DVI bytes into
+ 1322 longwords. However, since the TFM file consists of longwords, only
+ 1323 tfm_longword is need. [[This is also VAX dependent. It would not be
+ 1324 possible to use stdio's longword reading function getw here, because the
+ 1325 bytes have to be reversed.]] */
+ 1326
+ 1327 #define tfm_longword { lcx.uc[3] = getc(tfmfile); \
+ 1328 lcx.uc[2] = getc(tfmfile); lcx.uc[1] = getc(tfmfile); \
+ 1329 lcx.uc[0] = getc(tfmfile); }
+ 1330
+
+DVI2LN3 14-OCT-1985 13:19:13 VAX C V2.0-003 Page 26
+V1.0 14-OCT-1985 13:19:01 USER$4:[TEX.LN03.SOURCES]DVI2LN3.C;40 (1)
+
+ 1331 /* Read_tfm_file obtains the character widths from the TFM file
+ 1332 corresponding to font nf. */
+ 1333
+ 1334 int read_tfm_file() {
+ 1335 1
+ 1336 1 int i,lh,nw;
+ 1337 1 int info[256];
+ 1338 1 long z,alpha,beta;
+ 1339 1 long width[256];
+ 1340 1
+ 1341 1 open_tfm_file();
+ 1342 1 if (tfmfile == NULL) {
+ 1343 2 printf("\n Can't open TFM file for font %s",font_name[nf]);
+ 1344 2 return(1); }
+ 1345 1
+ 1346 1 /* The TFM format is described in some issue of the TUGBoat (TeX users'
+ 1347 1 group newsletter), and in the comments to the program TFtoPL. Here we
+ 1348 1 summarize those aspects of TFM format that are relevant to the task of
+ 1349 1 extracting the widths of the characters.
+ 1350 1
+ 1351 1 The first 24 bytes of a TFM file contain twelve 16-bit integers that give
+ 1352 1 the lengths of the various subsequent portions of the file. The ones
+ 1353 1 relevant to our purposes are LH, length of the header data, BC, the
+ 1354 1 smallest character code in the font, EC, the largest character code in the
+ 1355 1 font, and NW, number of words in the width table. So, we read those right
+ 1356 1 now, and then skip over the remainder, and then over a set of LH longwords
+ 1357 1 called the "header." */
+ 1358 1
+ 1359 1 tfm_longword;
+ 1360 1 lh = 256*lcx.uc[1] + lcx.uc[0];
+ 1361 1 tfm_longword;
+ 1362 1 txfa[nf] -> bc = 256*lcx.uc[3] + lcx.uc[2];
+ 1363 1 txfa[nf] -> ec = 256*lcx.uc[1] + lcx.uc[0];
+ 1364 1 tfm_longword;
+ 1365 1 nw = 256*lcx.uc[3] + lcx.uc[2];
+ 1366 1 if (txfa[nf] -> bc > 255 || txfa[nf] -> ec > 255 ||
+ 1367 1 txfa[nf] -> bc > txfa[nf] -> ec || nw > 256) {
+ 1368 2 printf("\n Bad TFM file for font %s",font_name[nf]);
+ 1369 2 return(1);
+ 1370 2 }
+ 1371 1
+ 1372 1 for(i=0; i<lh+3; i++) tfm_longword;
+ 1373 1
+ 1374 1 /* After the header, there are two arrays in the TFM file that interest us.
+ 1375 1 The first, INFO, is EC-BC+1 longwords long and contains pointers to the
+ 1376 1 second, WIDTH, which is NW longwords long. For each character i, the width
+ 1377 1 of i is WIDTH[INFO[i-BC]]. We read these arrays into memory. */
+ 1378 1
+ 1379 1 for(i=0; i<txfa[nf] -> ec-txfa[nf] -> bc+1; i++) {
+ 1380 2 tfm_longword;
+ 1381 2 if (lcx.uc[3] >= nw) {
+
+DVI2LN3 14-OCT-1985 13:19:13 VAX C V2.0-003 Page 27
+V1.0 14-OCT-1985 13:19:01 USER$4:[TEX.LN03.SOURCES]DVI2LN3.C;40 (1)
+
+ 1382 3 printf("\n Bad TFM file for font %s",font_name[nf]);
+ 1383 3 return(1);
+ 1384 3 }
+ 1385 2 info[i] = lcx.uc[3];
+ 1386 2 }
+ 1387 1
+ 1388 1 /* The widths are stored in a rather strange format known as a "fix-word."
+ 1389 1 A nonnegative width is expressed in "fix-word" format by expressing it in
+ 1390 1 units of 2^-20 times the design size. A negative width is expressed in
+ 1391 1 "fix-word" format by expressing its negative in those units, and then
+ 1392 1 changing the most significant byte to 255.
+ 1393 1
+ 1394 1 One needs to convert these widths into DVI units, multiplying by the scaled
+ 1395 1 design size according to a certain arcane algorithm. The algorithm is
+ 1396 1 copied from DVItype, to which we refer the reader for an explanation. */
+ 1397 1
+ 1398 1 z = txfa[nf] -> scaled_size;
+ 1399 1 alpha = 16*z; beta = 16;
+ 1400 1 while (z >= 4*(8*8*8*8*8*8*8)) { z = z/2; beta = beta/2; }
+ 1401 1 for(i=0; i<nw; i++) {
+ 1402 2 tfm_longword;
+ 1403 2 width[i] = ( ( (lcx.uc[0]*z)/256 + lcx.uc[1]*z )/256 +
+ 1404 2 lcx.uc[2]*z)/beta;
+ 1405 2 if (lcx.uc[3] == 255) width[i] -= alpha;
+ 1406 2 }
+ 1407 1
+ 1408 1 fclose(tfmfile);
+ 1409 1
+ 1410 1 /* Using these two arrays, we now compute the widths of the characters in
+ 1411 1 the fonts and place them into two malloc'ed arrays, one for the widths in
+ 1412 1 DVI units, one for the width in pixel units. */
+ 1413 1
+ 1414 1 font_width[nf] = malloc(4*(txfa[nf] -> ec+1));
+ 1415 1
+ 1416 1 for (i=0; i<txfa[nf] -> bc; i++) font_width[nf][i] = 0;
+ 1417 1 for (i=txfa[nf] -> bc; i <= txfa[nf] -> ec; i++)
+ 1418 1 font_width[nf][i] = width[info[i-txfa[nf] -> bc]];
+ 1419 1 return(0);
+ 1420 1 }
+ 1421
+ 1422 /* Open_tfm_file finds and opens the tfm file corresponding to a font nf.
+ 1423 The global file variable tfmfile is used to hold the file pointer. [[This
+ 1424 function will not work if the TFM file lies over the net on a VMS V3.x
+ 1425 host, because C file opens do not work in such circumstances. The problem
+ 1426 can be ignored, because eventually there should be no VMS V3.x hosts
+ 1427 left.]] */
+ 1428
+ 1429 int open_tfm_file () {
+ 1430 1
+ 1431 1 int jext,jnam;
+ 1432 1 char filespec[FILESPECLEN];
+
+DVI2LN3 14-OCT-1985 13:19:13 VAX C V2.0-003 Page 28
+V1.0 14-OCT-1985 13:19:01 USER$4:[TEX.LN03.SOURCES]DVI2LN3.C;40 (1)
+
+ 1433 1
+ 1434 1 find_VMS_filename(font_name[nf],&jnam,&jext);
+ 1435 1 filespec[0] = '\0';
+ 1436 1
+ 1437 1 /* If there is no directory part, fill in using the logical tex$fonts */
+ 1438 1
+ 1439 1 if (jnam == 0) strcpy(filespec,"tex$fonts:");
+ 1440 1 strcat(filespec,font_name[nf]);
+ 1441 1
+ 1442 1 /* if there is no extension, add the extension ".tfm" */
+ 1443 1
+ 1444 1 if (font_name[nf][jext] == '\0') strcat(filespec,".tfm");
+ 1445 1 tfmfile = fopen(filespec,"r");
+ 1446 1
+ 1447 1 }
+ 1448
+ 1449 /* Define_font_pass2 skips a font definition from the DVI file. */
+ 1450
+ 1451 int define_font_pass2()
+ 1452 {
+ 1453 1 unsigned char p,n;
+ 1454 1 int i;
+ 1455 1 four_bytes;
+ 1456 1 four_bytes;
+ 1457 1 four_bytes;
+ 1458 1 p = getc(dvifile); n = getc(dvifile);
+ 1459 1 for (i=0; i<p+n; i++) getc(dvifile);
+ 1460 1 }
+ 1461
+ 1462 /* Do_rule writes into the ln3 file the escape sequence corresponding
+ 1463 to a rule. */
+ 1464
+ 1465 int do_rule(xx0,yy0,xx1,yy1)
+ 1466 int xx0,yy0,xx1,yy1;
+ 1467 {
+ 1468 1 int j;
+ 1469 1
+ 1470 1 xx0 = min(xx0+hoff,maxrmar);
+ 1471 1 xx1 = min(xx1+hoff,maxrmar);
+ 1472 1 xx0 = max(xx0,0);
+ 1473 1 xx1 = max(xx1,0);
+ 1474 1 yy0 = min(yy0+voff,maxbmar);
+ 1475 1 yy1 = min(yy1+voff,maxbmar);
+ 1476 1 yy0 = max(yy0,0);
+ 1477 1 yy1 = max(yy1,0);
+ 1478 1 if (xx0 > xx1) { j = xx0; xx0 = xx1; xx1 = j; }
+ 1479 1 if (yy0 > yy1) { j = yy0; yy0 = yy1; yy1 = j; }
+ 1480 1
+ 1481 1 if ((yy1 != yy0 && xx1 != xx0)) {
+ 1482 2 fprintf(outfile,"\033[1;%d;%d;%d;%d!|",
+ 1483 2 xx0,yy0,yy1-yy0,xx1-xx0);
+
+DVI2LN3 14-OCT-1985 13:19:13 VAX C V2.0-003 Page 29
+V1.0 14-OCT-1985 13:19:01 USER$4:[TEX.LN03.SOURCES]DVI2LN3.C;40 (1)
+
+ 1484 2 inc_ln3p(25);
+ 1485 2 }
+ 1486 1 }
+ 1487
+ 1488 /* Set_v is called to execute vertical-position-altering commands, other
+ 1489 than pops. It modifies v and vv, and outputs the vertical position to the
+ 1490 LN3 file. We don't follow Stanford rules here. They sometimes set the
+ 1491 vertical position in pixels vv to something other than the rounded value of
+ 1492 v. Not following Stanford rules implies, for example, that the relative
+ 1493 vertical positions of an accent and its accentee may differ by one pixel
+ 1494 according to how the baseline of the accentee gets rounded. [[This should
+ 1495 perhaps be fixed.]] */
+ 1496
+ 1497 int set_v(v1)
+ 1498 int v1;
+ 1499 {
+ 1500 1 int l;
+ 1501 1
+ 1502 1 l = pixel_round(v1);
+ 1503 1 v = v1;
+ 1504 1 vv = l;
+ 1505 1 vpset = 0;
+ 1506 1 }
+ 1507
+ 1508 /* Set_h is called whenever a DVI command is encountered that alters the
+ 1509 horizonal position, other than a set_char, set_rule or pop. It sets h to
+ 1510 the new value, and alters hh according to Stanford rules, printing the new
+ 1511 hh in the LN3 file. */
+ 1512
+ 1513 int set_h(new_h)
+ 1514 int new_h;
+ 1515 {
+ 1516 1 int l,old_hh;
+ 1517 1
+ 1518 1 old_hh = hh;
+ 1519 1 l = pixel_round(new_h);
+ 1520 1 if (txfa[curf] == 0 || new_h-h >= txfa[curf] -> space
+ 1521 1 || new_h-h <= -4*txfa[curf] -> space) hh = l;
+ 1522 1 else {
+ 1523 2 hh += pixel_round(new_h-h);
+ 1524 2 if (hh-l > MAX_DRIFT) hh = l+MAX_DRIFT;
+ 1525 2 else if (hh-l < -MAX_DRIFT) hh = l-MAX_DRIFT;
+ 1526 2 }
+ 1527 1 h = new_h;
+ 1528 1 return(0);
+ 1529 1 }
+
+
+
+Command Line
+------------
+
+DVI2LN3 14-OCT-1985 13:19:13 VAX C V2.0-003 Page 30
+V1.0 14-OCT-1985 13:19:01 USER$4:[TEX.LN03.SOURCES]DVI2LN3.C;40 (1)
+
+
+CC/DEB/LIS DVI2LN3
+