% dvitomp.ch for C compilation with web2c. % % Copyright 1990 - 1995 by AT&T Bell Laboratories. % % Permission to use, copy, modify, and distribute this software % and its documentation for any purpose and without fee is hereby % granted, provided that the above copyright notice appear in all % copies and that both that the copyright notice and this % permission notice and warranty disclaimer appear in supporting % documentation, and that the names of AT&T Bell Laboratories or % any of its entities not be used in advertising or publicity % pertaining to distribution of the software without specific, % written prior permission. % % Change file for the DVItype processor, for use with WEB to C % This file was created by John Hobby. It is loosely based on the % change file for the WEB to C version of dvitype (due to Howard % Trickey and Pavel Curtis). % % 3/11/90 (JDH) Original version. % 4/30/90 (JDH) Update to handle virtual fonts % 4/16/93 (JDH) Make output go to standard output and require mpx file % to be a command line argument. % % 1/18/95 (UV) Update based on dvitype.ch for web2c-6.1 % 4/13/95 (UV) Cosmetic changes for release of web2c-mp % 10/08/95 (UV) Bug fix: need to replace abs() with floating-point arg % by fabs() because of different definition in cpascal.h % as reported by Dane Dwyer . @x [0] WEAVE: print changes only. \pageno=\contentspagenumber \advance\pageno by 1 @y \pageno=\contentspagenumber \advance\pageno by 1 \let\maybe=\iffalse \def\title{DVI$\,$\lowercase{to}MP changes for C} @z @x [1] Duplicate banner line for use in |print_version_and_exit|. @d banner=='% Written by DVItoMP, Version 0.64' {the first line of the output file} @y @d banner=='% Written by DVItoMP, Version 0.64' {the first line of the output file} @d term_banner=='This is DVItoMP, Version 0.64' {the same in the usual format, as it would be shown on a terminal} @z @x [3] Set up kpathsea. procedure initialize; {this procedure gets things started properly} var i:integer; {loop index for initializations} begin @@/ @y @ procedure initialize; {this procedure gets things started properly} var i:integer; {loop index for initializations} begin kpse_set_progname (argv[0]); {initialize for the filename searches} parse_arguments; @@/ @z @x [7] Remove non-local goto. @d abort(#)==begin err_print_ln('DVItoMP abort: ',#); history:=fatal_error; jump_out; end @d bad_dvi(#)==abort('Bad DVI file: ',#,'!') @.Bad DVI file@> @d warn(#)==begin err_print_ln('DVItoMP warning: ',#); history:=warning_given; end @p procedure jump_out; begin goto final_end; end; @y @d jump_out==uexit(history) @d abort(#)==begin err_print_ln('DVItoMP abort: ',#); history:=fatal_error; jump_out; end @d bad_dvi(#)==abort('Bad DVI file: ',#,'!') @.Bad DVI file@> @d warn(#)==begin err_print_ln('DVItoMP warning: ',#); history:=warning_given; end @z @x [11] Permissive input. @!ASCII_code=" ".."~"; {a subrange of the integers} @y @!ASCII_code=0..255; {a subrange of the integers} @z % [12] The text_char type is used as an array index into `xord'. The % default type `char' produces signed integers, which are bad array % indices in C. @x @d text_char == char {the data type of characters in text files} @d first_text_char=0 {ordinal number of the smallest element of |text_char|} @d last_text_char=127 {ordinal number of the largest element of |text_char|} @y @d text_char == ASCII_code {the data type of characters in text files} @d first_text_char=0 {ordinal number of the smallest element of |text_char|} @d last_text_char=255 {ordinal number of the largest element of |text_char|} @z @x [14] Fix up opening the files. @p procedure open_mpx_file; {prepares to write text on |mpx_file|} begin rewrite(mpx_file); end; @y @p procedure open_mpx_file; {prepares to write text on |mpx_file|} begin cur_name := extend_filename (mpx_name, 'mpx'); rewrite (mpx_file, cur_name); end; @z @x [19] More file opening. @p procedure open_dvi_file; {prepares to read packed bytes in |dvi_file|} begin reset(dvi_file); if eof(dvi_file) then abort('DVI file not found'); end; @# function open_tfm_file:boolean; {prepares to read packed bytes in |tfm_file|} begin reset(tfm_file,cur_name); open_tfm_file:=(not eof(tfm_file)); end; @# function open_vf_file:boolean; {prepares to read packed bytes in |vf_file|} begin reset(vf_file,cur_name); open_vf_file:=(not eof(vf_file)); end; @y @p procedure open_dvi_file; {prepares to read packed bytes in |dvi_file|} begin cur_name := extend_filename (dvi_name, 'dvi'); resetbin(dvi_file, cur_name); end; @# function open_tfm_file:boolean; {prepares to read packed bytes in |tfm_file|} begin tfm_file := kpse_open_file (cur_name, kpse_tfm_format); free (cur_name); {We |xmalloc|'d this before we got called.} open_tfm_file := true; {If we get here, we succeeded.} end; @# function open_vf_file:boolean; {prepares to read packed bytes in |tfm_file|} var @!full_name:^char; begin {It's ok if the \.{VF} file doesn't exist.} full_name := kpse_find_vf (cur_name); if full_name then begin resetbin (vf_file, full_name); free (cur_name); free (full_name); open_vf_file := true; end else open_vf_file := false; end; @z @x [24] No arbitrary limit on filename length. @!cur_name:packed array[1..name_length] of char; {external name, with no lower case letters} @y @!cur_name:^char; {external name} @z @x [26] Make get_n_bytes routines work with 16-bit math. get_two_bytes:=a*256+b; @y get_two_bytes:=a*toint(256)+b; @z @x get_three_bytes:=(a*256+b)*256+c; @y get_three_bytes:=(a*toint(256)+b)*256+c; @z @x if a<128 then signed_trio:=(a*256+b)*256+c else signed_trio:=((a-256)*256+b)*256+c; @y if a<128 then signed_trio:=(a*toint(256)+b)*256+c else signed_trio:=((a-toint(256))*256+b)*256+c; @z @x if a<128 then signed_quad:=((a*256+b)*256+c)*256+d else signed_quad:=(((a-256)*256+b)*256+c)*256+d; @y if a<128 then signed_quad:=((a*toint(256)+b)*256+c)*256+d else signed_quad:=(((a-256)*toint(256)+b)*256+c)*256+d; @z @x [41] Fix abs() with floating-point arg. begin if abs(font_scaled_size[f]-font_scaled_size[ff]) @y begin if fabs(font_scaled_size[f]-font_scaled_size[ff]) @z @x [43] Fix abs() with floating-point arg. if abs(font_design_size[f]-font_design_size[ff]) > font_tolerance then @y if fabs(font_design_size[f]-font_design_size[ff]) > font_tolerance then @z @x [46] Make 16-bit TFM calculations work. read_tfm_word; lh:=b2*256+b3; read_tfm_word; font_bc[f]:=b0*256+b1; font_ec[f]:=b2*256+b3; @y read_tfm_word; lh:=b2*toint(256)+b3; read_tfm_word; font_bc[f]:=b0*toint(256)+b1; font_ec[f]:=b2*toint(256)+b3; @z @x if b0<128 then tfm_check_sum:=((b0*256+b1)*256+b2)*256+b3 else tfm_check_sum:=(((b0-256)*256+b1)*256+b2)*256+b3; @y if b0<128 then tfm_check_sum:=((b0*toint(256)+b1)*256+b2)*256+b3 else tfm_check_sum:=(((b0-256)*toint(256)+b1)*256+b2)*256+b3; @z % [61] Don't set default_directory_name. @x @d default_directory_name=='TeXfonts:' {change this to the correct name} @d default_directory_name_length=9 {change this to the correct length} @= @!default_directory:packed array[1..default_directory_name_length] of char; @y There is no single |default_directory| with C. @z @x [62] Remove initialization of default_directory. @ @= default_directory:=default_directory_name; @y @ (No initialization needs to be done. Keep this module to preserve numbering.) @z @x [63] Dynamically allocate cur_name, don't add .vf. for k:=1 to name_length do cur_name[k]:=' '; if area_length[f]=0 then begin for k:=1 to default_directory_name_length do cur_name[k]:=default_directory[k]; l:=default_directory_name_length; end else l:=0; for k:=font_name[f] to font_name[f+1]-1 do begin incr(l); if l+3>name_length then abort('DVItoMP capacity exceeded (max font name length=', name_length:1,')!'); @.DVItoMP capacity exceeded...@> if (names[k]>="a")and(names[k]<="z") then cur_name[l]:=xchr[names[k]-@'40] else cur_name[l]:=xchr[names[k]]; end; cur_name[l+1]:='.'; cur_name[l+2]:='V'; cur_name[l+3]:='F' @y {This amounts to a string copy. } cur_name := xmalloc ((font_name[f+1] - font_name[f]) + 1); for k:=font_name[f] to font_name[f+1]-1 do begin cur_name[k - font_name[f]] := xchr[names[k]]; end; cur_name[font_name[f+1] - font_name[f]] := 0; @z @x [64] Since we didn't add .vf, don't need to change it to .tfm. l:=area_length[f]; if l=0 then l:=default_directory_name_length; l:=l+font_name[f+1]-font_name[f]; if l+4>name_length then abort('DVItoMP capacity exceeded (max font name length=', name_length:1,')!'); @.DVItoMP capacity exceeded...@> cur_name[l+2]:='T'; cur_name[l+3]:='F'; cur_name[l+4]:='M' @y do_nothing @z @x [78] Fix printing of real numbers. if (abs(x)>=4096.0)or(abs(y)>=4096.0)or(m>=4096.0)or(m<0) then begin warn('text scaled ',m:1:1,@| ' at (',x:1:1,',',y:1:1,') is out of range'); end_char_string(60); end else end_char_string(40); print_ln(',_n',str_f:1,',',m:1:5,',',x:1:4,',',y:1:4,');'); @y if (fabs(x)>=4096.0)or(fabs(y)>=4096.0)or(m>=4096.0)or(m<0) then begin warn('text is out of range'); end_char_string(60); end else end_char_string(40); print(',_n',str_f:1,','); fprint_real(mpx_file, m,1,5); print(','); fprint_real(mpx_file, x,1,4); print(','); fprint_real(mpx_file, y,1,4); print_ln(');'); @z @x [79] Another fix for printing of real numbers. if (abs(xx1)>=4096.0)or(abs(yy1)>=4096.0)or@| (abs(xx2)>=4096.0)or(abs(yy2)>=4096.0)or(ww>=4096.0) then warn('hrule or vrule near (',xx1:1:1,',',yy1:1:1,') is out of range'); print_ln('_r((',xx1:1:4,',',yy1:1:4,')..(',xx2:1:4,',',yy2:1:4, '), ',ww:1:4,');'); @y if (fabs(xx1)>=4096.0)or(fabs(yy1)>=4096.0)or@| (fabs(xx2)>=4096.0)or(fabs(yy2)>=4096.0)or(ww>=4096.0) then warn('hrule or vrule is out of range'); print('_r(('); fprint_real(mpx_file, xx1,1,4); print(','); fprint_real(mpx_file, yy1,1,4); print(')..('); fprint_real(mpx_file, xx2,1,4); print(','); fprint_real(mpx_file, yy2,1,4); print('), '); fprint_real(mpx_file, ww,1,4); print_ln(');'); @z @x [80] Yet another fix for printing of real numbers. print_ln('setbounds _p to (0,',dd:1:4,')--(',w:1:4,',',dd:1:4,')--'); print_ln(' (',w:1:4,',',h:1:4,')--(0,',h:1:4,')--cycle;') @y print('setbounds _p to (0,'); fprint_real(mpx_file, dd,1,4); print(')--('); fprint_real(mpx_file, w,1,4); print(','); fprint_real(mpx_file, dd,1,4); print_ln(')--');@/ print(' ('); fprint_real(mpx_file, w,1,4); print(','); fprint_real(mpx_file, h,1,4); print(')--(0,'); fprint_real(mpx_file, h,1,4); print_ln(')--cycle;') @z @x [98] Main program. print_ln(banner); @y print (banner); print_ln (version_string); @z @x Exit with appropriate status. final_end:end. @y if history<=cksum_trouble then uexit(0) else uexit(history); end. @z @x [103] System-dependent changes. This section should be replaced, if necessary, by changes to the program that are necessary to make \.{DVItoMP} work at a particular installation. It is usually best to design your change file so that all changes to previous sections preserve the section numbering; then everybody's version will be consistent with the printed program. More extensive changes, which introduce new sections, can be inserted here; then only the index itself will get a new section number. @^system dependencies@> @y Parse a Unix-style command line. @d argument_is (#) == (strcmp (long_options[option_index].name, #) = 0) @ = procedure parse_arguments; const n_options = 2; {Pascal won't count array lengths for us.} var @!long_options: array[0..n_options] of getopt_struct; @!getopt_return_val: integer; @!option_index: c_int_type; @!current_option: 0..n_options; begin @; repeat getopt_return_val := getopt_long_only (argc, argv, '', long_options, address_of (option_index)); if getopt_return_val = -1 then begin {End of arguments; we exit the loop below.} ; end else if getopt_return_val = "?" then begin usage (1, 'dvitomp'); end else if argument_is ('help') then begin usage (0, DVITOMP_HELP); end else if argument_is ('version') then begin print_version_and_exit (term_banner, 'AT&T Bell Laboraties', 'John Hobby'); end; {Else it was a flag; |getopt| has already done the assignment.} until getopt_return_val = -1; {Now |optind| is the index of first non-option on the command line. We must have one or two remaining arguments.} if (optind + 1 <> argc) and (optind + 2 <> argc) then begin write_ln (stderr, 'dvitomp: Need one or two file arguments.'); usage (1, 'dvitomp'); end; dvi_name := cmdline (optind); if optind + 2 <= argc then begin mpx_name := cmdline (optind + 1); {The user specified the other name.} end else begin {User did not specify the other name; default it from the first.} mpx_name := basename_change_suffix (dvi_name, '.dvi', '.mpx'); end; end; @ Here are the options we allow. The first is one of the standard GNU options. @.-help@> @ = current_option := 0; long_options[current_option].name := 'help'; long_options[current_option].has_arg := 0; long_options[current_option].flag := 0; long_options[current_option].val := 0; incr (current_option); @ Another of the standard options. @.-version@> @ = long_options[current_option].name := 'version'; long_options[current_option].has_arg := 0; long_options[current_option].flag := 0; long_options[current_option].val := 0; incr (current_option); @ An element with all zeros always ends the list. @ = long_options[current_option].name := 0; long_options[current_option].has_arg := 0; long_options[current_option].flag := 0; long_options[current_option].val := 0; @ Global filenames. @ = @!dvi_name, @!mpx_name:c_string; @z