<> <> <<>> <> <<>> 003135: Change the banner line. @x @d banner=='This is GFtoDVI, Version 1.5' {printed when the program starts} @y @d banner=='This is GFtoPress 1.5, for Cedar 6.0' {printed when the program starts} @z 004446: Change write_ln to writeln, read_ln to readln, and max_int to maxint. Also, deflect output to the file |term_out|. @x @d print(#)==write(#) @d print_ln(#)==write_ln(#) @d print_nl(#)==begin write_ln; write(#); end @y @d write_ln==writeln @d read_ln==readln @d max_int==maxint @d print(#)==write(term_out, #) @d print_ln(#)==write_ln(term_out, #) @d print_nl(#)==begin write_ln(term_out); write(term_out, #); end @z 004692: Allow for external procedure and function declarations for things implemented directly in Cedar, rather than in Pascal. Also, declare the file |term_out| and open it and remove all traces of the file |output|. @x @p program GF_to_DVI(@!output); label @@/ const @@/ type @@/ var @@/ procedure initialize; {this procedure gets things started properly} var @!i,@!j,@!m,@!n:integer; {loop indices for initializations} begin print_ln(banner);@/ @y @p program GF_to_DVI; label @@/ const @@/ type @@/ var term_out : text_file; @@/ @@/ procedure initialize; {this procedure gets things started properly} var @!i,@!j,@!m,@!n:integer; {loop indices for initializations} begin tty_rewrite(term_out); print_ln(banner);@/ @z 005510: Increase file_name_size and eliminate dvi_buf_size. @x @!file_name_size=50; {a file name shouldn't be longer than this} @!font_mem_size=1000; {space for font metric data} @!dvi_buf_size=800; {size of the output buffer; must be a multiple of 8} @y @!file_name_size=128; {a file name shouldn't be longer than this} @!font_mem_size=1000; {space for font metric data} @z 010118: Change last_text_char to 255. @x @d last_text_char=127 {ordinal number of the largest element of |text_char|} @y @d last_text_char=255 {ordinal number of the largest element of |text_char|} @z 013543: Get rid of call to break. @x @d update_terminal == break(output) {empty the terminal output buffer} @y @d update_terminal == {In Cedar, we needn't do anything.} @z 013921: Do a reset on the TTY for input. @x begin update_terminal; reset(term_in); @y begin update_terminal; tty_reset(term_in); @z 076392: Remove declaration of dvi_file. @x @!dvi_file:byte_file; {the typesetting instructions we are writing} @y @z 076928: Hook up open calls to Cedar and remove open_dvi_file. @x @p procedure open_gf_file; {prepares to read packed bytes in |gf_file|} begin reset(gf_file,name_of_file); cur_loc:=0; end; @# procedure open_tfm_file; {prepares to read packed bytes in |tfm_file|} begin reset(tfm_file,name_of_file); end; @# procedure open_dvi_file; {prepares to write packed bytes in |dvi_file|} begin rewrite(dvi_file,name_of_file); end; @y @p procedure open_gf_file; {prepares to read packed bytes in |gf_file|} begin byte_file_reset(gf_file); cur_loc:=0; end; @# procedure open_tfm_file; {prepares to read packed bytes in |tfm_file|} begin byte_file_reset(tfm_file); end; @z 081931: Add arrays for Press font parameters. @x @!font_ec:array[internal_font_number] of eight_bits; {ending (largest) character code} @y @!font_ec:array[internal_font_number] of eight_bits; {ending (largest) character code} @!font_family : array [internal_font_number] of str_number; {The Press family name} @!font_face : array [internal_font_number] of eight_bits; {The Press face code} @!font_press_code : array [internal_font_number] of cedar_nat; {Once |font_used| is true, holds the SirPress font code} @z 086111: Add two new local variables to read_font_info. Also, declare the procedure |make_string| here. @x @p procedure read_font_info(@!f:integer;@!s:scaled); {input a \.{TFM} file} label done,bad_tfm; var k:0..font_mem_size; {index into |font_info|} @y @p @@/ procedure read_font_info(@!f:integer;@!s:scaled); {input a \.{TFM} file} label done,bad_tfm; var k:0..font_mem_size; {index into |font_info|} @!i, @!fam_len : 0..65535; @z 088532: Fix up the reading of the TFM header to get Press information. Also, move definitions of append_char and str_room to make this possible. @x @ Only the first two words of the header are needed by \.{GFtoDVI}. @d store_four_quarters(#)== begin read_tfm_word; qw.b0:=qi(b0); qw.b1:=qi(b1); qw.b2:=qi(b2); qw.b3:=qi(b3); #:=qw; end @= begin if lh<2 then abend; store_four_quarters(font_check[f]); read_tfm_word; if b0>127 then abend; {design size must be positive} z:=((b0*256+b1)*256+b2)*16+(b3 div 16); if z2 do begin read_tfm_word; decr(lh); {ignore the rest of the header} end; font_dsize[f]:=z; if s>0 then z:=s; font_size[f]:=z; end @y @ Only the first two words of the header are needed by \.{GFtoDVI}, but \.{GFtoPress} must read the first 18 of them, getting the family and face information. The definitions of |append_char| and |str_room| have been moved to here from their later position so that we can make a string out of the family name. @d store_four_quarters(#)== begin read_tfm_word; qw.b0:=qi(b0); qw.b1:=qi(b1); qw.b2:=qi(b2); qw.b3:=qi(b3); #:=qw; end @d append_char(#) == {put |ASCII_code| \# at the end of |str_pool|} begin str_pool[pool_ptr]:=#; incr(pool_ptr); end @d str_room(#) == {make sure that the pool hasn't overflowed} begin if pool_ptr+# > pool_size then abort('Too many strings!'); @.Too many strings@> end @= begin if lh<18 then abend; store_four_quarters(font_check[f]); read_tfm_word; if b0>127 then abend; {design size must be positive} z:=((b0*256+b1)*256+b2)*16+(b3 div 16); if z18 do begin read_tfm_word; decr(lh); {ignore the rest of the header} end; font_dsize[f]:=z; if s>0 then z:=s; font_size[f]:=z; end @z 094626: Remove definitions of append_char and str_room (see previous change) @x @d append_char(#) == {put |ASCII_code| \# at the end of |str_pool|} begin str_pool[pool_ptr]:=#; incr(pool_ptr); end @d str_room(#) == {make sure that the pool hasn't overflowed} begin if pool_ptr+# > pool_size then abort('Too many strings!'); @.Too many strings@> end @y The definitions of |append_char| and |str_room| have been moved from here to module 62 because we needed them earlier in \.{GFtoPress} than they did in \.{GFtoDVI}. @z 094626: Make |make_string| into a named module so that we can move it. @x @p function make_string : str_number; {current string enters the pool} @y @= function make_string : str_number; {current string enters the pool} @z 096495: Allow 21-character initial strings, such as the TFM file area name. @x @d init_str13(#)==buffer[13]:=#; init_str12 @y @d init_str13(#)==buffer[13]:=#; init_str12 @d init_str14(#)==buffer[14]:=#; init_str13 @d init_str15(#)==buffer[15]:=#; init_str14 @d init_str16(#)==buffer[16]:=#; init_str15 @d init_str17(#)==buffer[17]:=#; init_str16 @d init_str18(#)==buffer[18]:=#; init_str17 @d init_str19(#)==buffer[19]:=#; init_str18 @d init_str20(#)==buffer[20]:=#; init_str19 @d init_str21(#)==buffer[21]:=#; init_str20 @z 098992: Change dvi_ext into press_ext @x @d dvi_ext=max_keyword+2 {string number for `\.{.dvi}'} @y @d press_ext=max_keyword+2 {string number for `\.{.press}'} @z 098992: Finish changing dvi_ext into press_ext @x l:=4; init_str4(".")("d")("v")("i")(dvi_ext);@/ @y l:=6; init_str6(".")("p")("r")("e")("s")("s")(press_ext);@/ @z 106965: Use the proper home_font_area: ///Fonts/FontMetrics/ @x l:=9; init_str9("T")("e")("X")("f")("o")("n")("t")("s")(":")(home_font_area);@/ @y l:=21; init_str21("/")("/")("/")("F")("o")("n")("t")("s")@/ ("/")("F")("o")("n")("t")("M")("e")("t")("r")("i")("c")("s")("/")@/ (home_font_area); @z 107360: Fix parsing of filenames. @x else begin if (c=">")or(c=":") then @y else begin if (c=">")or(c="/")or(c="]") then @z 109789: Fix getting argument from command line. @x @p procedure start_gf; label found,done; begin loop@+begin print_nl('GF file name: '); input_ln; @y @p procedure start_gf; label found,done; begin loop@+begin if command_line_already_gotten then begin print_nl('GF file name: '); input_ln; end else begin get_command_line; command_line_already_gotten := true; end; @z 110332: Fix opening Press file. @x found:job_name:=cur_name; pack_file_name(job_name,null_string,dvi_ext); open_dvi_file; @y found:job_name:=cur_name; pack_file_name(job_name,null_string,press_ext); press_open_file; @z 112920: Replace writing DVI font_def commands with getting SirPress font codes. @x dvi_font_def(f); {put the font name in the \.{DVI} file} @y font_press_code[f] := press_get_font_code(f); @z 113086: (BUG) Fix looping to avoid unreachable code. @x @ @= loop@+ begin not_found: print_nl('Special font substitution: '); @.Special font subst...@> continue: input_ln; if line_length=0 then goto done; @; print('Please say, e.g., "grayfont foo" or "slantfontarea baz".'); goto not_found; found: @; print('OK; any more? '); goto continue; end; done: @y @ @= begin not_found: print_nl('Special font substitution: '); @.Special font subst...@> loop@+ begin input_ln; if line_length=0 then goto done; @; print('Please say, e.g., "grayfont foo" or "slantfontarea baz".'); goto not_found; found: @; print('OK; any more? '); end; end; done: @z 114979: Remove some useless DVI modules and change others. @x @* Shipping pages out. The following routines are used to write the \.{DVI} file. They have been copied from \TeX, but simplified; we don't have to handle nearly as much generality as \TeX\ does. Statistics about the entire set of pages that will be shipped out must be reported in the \.{DVI} postamble. The global variables |total_pages|, |max_v|, |max_h|, and |last_bop| are used to record this information. @= @!total_pages:integer; {the number of pages that have been shipped out} @!max_v:scaled; {maximum height-plus-depth of pages shipped so far} @!max_h:scaled; {maximum width of pages shipped so far} @!last_bop:integer; {location of previous |bop| in the \.{DVI} output} @ @= total_pages:=0; max_v:=0; max_h:=0; last_bop:=-1; @ The \.{DVI} bytes are output to a buffer instead of being written directly to the output file. This makes it possible to reduce the overhead of subroutine calls. The output buffer is divided into two parts of equal size; the bytes found in |dvi_buf[0..half_buf-1]| constitute the first half, and those in |dvi_buf[half_buf..dvi_buf_size-1]| constitute the second. The global variable |dvi_ptr| points to the position that will receive the next output byte. When |dvi_ptr| reaches |dvi_limit|, which is always equal to one of the two values |half_buf| or |dvi_buf_size|, the half buffer that is about to be invaded next is sent to the output and |dvi_limit| is changed to its other value. Thus, there is always at least a half buffer's worth of information present, except at the very beginning of the job. Bytes of the \.{DVI} file are numbered sequentially starting with 0; the next byte to be generated will be number |dvi_offset+dvi_ptr|. @= @!dvi_index=0..dvi_buf_size; {an index into the output buffer} @ Some systems may find it more efficient to make |dvi_buf| a |packed| array, since output of four bytes at once may be facilitated. @^system dependencies@> @= @!dvi_buf:array[dvi_index] of eight_bits; {buffer for \.{DVI} output} @!half_buf:dvi_index; {half of |dvi_buf_size|} @!dvi_limit:dvi_index; {end of the current half buffer} @!dvi_ptr:dvi_index; {the next available buffer address} @!dvi_offset:integer; {|dvi_buf_size| times the number of times the output buffer has been fully emptied} @ Initially the buffer is all in one piece; we will output half of it only after it first fills up. @= half_buf:=dvi_buf_size div 2; dvi_limit:=dvi_buf_size; dvi_ptr:=0; dvi_offset:=0; @ The actual output of |dvi_buf[a..b]| to |dvi_file| is performed by calling |write_dvi(a,b)|. It is safe to assume that |a| and |b+1| will both be multiples of 4 when |write_dvi(a,b)| is called; therefore it is possible on many machines to use efficient methods to pack four bytes per word and to output an array of words with one system call. @^system dependencies@> @p procedure write_dvi(@!a,@!b:dvi_index); var k:dvi_index; begin for k:=a to b do write(dvi_file,dvi_buf[k]); end; @ To put a byte in the buffer without paying the cost of invoking a procedure each time, we use the macro |dvi_out|. @d dvi_out(#)==@+begin dvi_buf[dvi_ptr]:=#; incr(dvi_ptr); if dvi_ptr=dvi_limit then dvi_swap; end @p procedure dvi_swap; {outputs half of the buffer} begin if dvi_limit=dvi_buf_size then begin write_dvi(0,half_buf-1); dvi_limit:=half_buf; dvi_offset:=dvi_offset+dvi_buf_size; dvi_ptr:=0; end else begin write_dvi(half_buf,dvi_buf_size-1); dvi_limit:=dvi_buf_size; end; end; @ Here is how we clean out the buffer when \TeX\ is all through; |dvi_ptr| will be a multiple of~4. @= if dvi_limit=half_buf then write_dvi(half_buf,dvi_buf_size-1); if dvi_ptr>0 then write_dvi(0,dvi_ptr-1) @ The |dvi_four| procedure outputs four bytes in two's complement notation, without risking arithmetic overflow. @p procedure dvi_four(@!x:integer); begin if x>=0 then dvi_out(x div @'100000000) else begin x:=x+@'10000000000; x:=x+@'10000000000; dvi_out((x div @'100000000) + 128); end; x:=x mod @'100000000; dvi_out(x div @'200000); x:=x mod @'200000; dvi_out(x div @'400); dvi_out(x mod @'400); end; @ Here's a procedure that outputs a font definition. @d select_font(#)==dvi_out(fnt_num_0+#) {set current font to \#} @p procedure dvi_font_def(@!f:internal_font_number); var k:integer; {index into |str_pool|} begin dvi_out(fnt_def1); dvi_out(f);@/ dvi_out(qo(font_check[f].b0)); dvi_out(qo(font_check[f].b1)); dvi_out(qo(font_check[f].b2)); dvi_out(qo(font_check[f].b3));@/ dvi_four(font_size[f]); dvi_four(font_dsize[f]);@/ dvi_out(length(font_area[f])); dvi_out(length(font_name[f])); @; end;@/ @t\4@>@@; @ @= for k:=str_start[font_area[f]] to str_start[font_area[f]+1]-1 do dvi_out(str_pool[k]); for k:=str_start[font_name[f]] to str_start[font_name[f]+1]-1 do dvi_out(str_pool[k]) @y @* Shipping pages out. The next several modules dealt with DVI files in the original version of this program. Since we are producing Press files, we don't need them, but we keep their places around to keep the module numbers the same. This was module number 102. @= @!total_pages:integer; {the number of pages that have been shipped out} @ @= total_pages:=0; @ (104) @ (105) @ (106) @ (107) @ (108) @ (109) @ (110) @ (111) @d select_font == press_set_font @p @ @ (112) @z 119275: Fix the typeset procedure. @x @p procedure typeset(@!c:eight_bits); begin if c>=128 then dvi_out(set1); dvi_out(c); end; @y @d typeset == press_set_char @z 119367: Change dvi_scaled to use typeset instead of dvi_out. @x @ The |dvi_scaled| subroutine takes a |real| value |x| and outputs a decimal approximation to |x/unity|, correct to one decimal place. @p procedure dvi_scaled(@!x:real); var @!n:integer; {an integer approximation to |10*x/unity|} @!m:integer; {the integer part of the answer} @!k:integer; {the number of digits in |m|} begin n:=round(x/6553.6); if n<0 then begin dvi_out("-"); n:=-n; end; m:=n div 10; k:=0; repeat incr(k); buffer[k]:=(m mod 10)+"0"; m:=m div 10; until m=0; repeat dvi_out(buffer[k]); decr(k); until k=0; if n mod 10 <> 0 then begin dvi_out("."); dvi_out((n mod 10)+"0"); end; end; @y @ The |dvi_scaled| subroutine takes a |real| value |x| and outputs a decimal approximation to |x/unity|, correct to one decimal place. @p procedure dvi_scaled(@!x:real); var @!n:integer; {an integer approximation to |10*x/unity|} @!m:integer; {the integer part of the answer} @!k:integer; {the number of digits in |m|} begin n:=round(x/6553.6); if n<0 then begin typeset("-"); n:=-n; end; m:=n div 10; k:=0; repeat incr(k); buffer[k]:=(m mod 10)+"0"; m:=m div 10; until m=0; repeat typeset(buffer[k]); decr(k); until k=0; if n mod 10 <> 0 then begin typeset("."); typeset((n mod 10)+"0"); end; end; @z 119976: Simplify the finishing up procedure. @x @ At the end of the program, we must finish things off by writing the post\-amble. An integer variable~|k| will be declared for use by this routine. @= begin dvi_out(post); {beginning of the postamble} dvi_four(last_bop); last_bop:=dvi_offset+dvi_ptr-5; {|post| location} dvi_four(25400000); dvi_four(473628672); {conversion ratio for sp} dvi_four(1000); {magnification factor} dvi_four(max_v); dvi_four(max_h);@/ dvi_out(0); dvi_out(3); {`\\{max\_push}' is said to be 3}@/ dvi_out(total_pages div 256); dvi_out(total_pages mod 256);@/ if not fonts_not_loaded then for k:=title_font to logo_font do if length(font_name[k])>0 then dvi_font_def(k); dvi_out(post_post); dvi_four(last_bop); dvi_out(dvi_id_byte);@/ k:=4+((dvi_buf_size-dvi_ptr) mod 4); {the number of 223's} while k>0 do begin dvi_out(223); decr(k); end; @; goto final_end; end @y @ At the end of the program, we must finish things off by closing the Press file. @= begin press_close_file; goto final_end; end @z 123060: Change kerning for Press @x begin dvi_out(right4); dvi_four(kern_amount); @y begin press_move_x(kern_amount); @z 152960: Another change for Press: remove |eop| and DVI-bookkeeping of page widths and insert a press_write_page. @x @= begin check_fonts; @; @; @; print('[',total_pages:1); update_terminal; {print a progress report} @; @; do_pixels; dvi_out(eop); {finish the page} @; print(']'); update_terminal; end @y @= begin check_fonts; @; @; @; print('[',total_pages:1); update_terminal; {print a progress report} @; @; do_pixels; press_write_page; {finish the page} print(']'); update_terminal; end @z 155404: Remove DVI bookkeeping variables @x @!page_height,page_width:scaled; {size of the current page} @y @z 156655: Remove DVI bookkeeping @x page_height:=round(unsc_y_ratio*(max_y+1-pre_min_y))+3276800-offset_y; if page_height>max_v then max_v:=page_height; page_width:=over_col-10000000 @y @z 156803: Fix dvi_goto @x @ The |dvi_goto| subroutine outputs bytes to the \.{DVI} file that will initiate typesetting at given \.{DVI} coordinates, assuming that the current position of the \.{DVI} reader is $(0,0)$. This subroutine begins by outputting a |push| command; therefore, a |pop| command should be given later. That |pop| will restore the \.{DVI} position to $(0,0)$. @p procedure dvi_goto(@!x,@!y:scaled); begin dvi_out(push); if x<>0 then begin dvi_out(right4); dvi_four(x); end; if y<>0 then begin dvi_out(down4); dvi_four(y); end; end; @y @ The |dvi_goto| subroutine used to output bytes to the \.{DVI} file that would initiate typesetting at given \.{DVI} coordinates, assuming that the current position of the \.{DVI} reader is $(0,0)$. We've made things simpler by pushing the issue into Cedar. @d dvi_goto == press_goto @z 157339: Remove |bop| output @x @ @= dvi_out(bop); incr(total_pages); dvi_four(total_pages); dvi_four(char_code); dvi_four(fam); for k:=3 to 9 do dvi_four(0); dvi_four(last_bop); last_bop:=dvi_offset+dvi_ptr-45;@/ dvi_goto(0,655360); {the top baseline is 10\thinspace pt down} @y @ @= incr(total_pages); @z 158051: Remove a |pop| @x if title_head<>null then begin right[title_tail]:=null; repeat hbox(left_quotes,title_font,true); hbox(info[title_head],title_font,true); hbox(right_quotes,title_font,true); title_head:=right[title_head]; until title_head=null; end; dvi_out(pop) @y if title_head<>null then begin right[title_tail]:=null; repeat hbox(left_quotes,title_font,true); hbox(info[title_head],title_font,true); hbox(right_quotes,title_font,true); title_head:=right[title_head]; until title_head=null; end; @z 159232: Fix output of rules @x @ @= begin if temp_y>dvi_y then begin k:=temp_y; temp_y:=dvi_y; dvi_y:=k; end; dvi_goto(dvi_x-(rule_size[p] div 2), dvi_y); dvi_out(put_rule); dvi_four(dvi_y-temp_y); dvi_four(rule_size[p]); dvi_out(pop); end @ @= begin if temp_x= begin if temp_y>dvi_y then begin k:=temp_y; temp_y:=dvi_y; dvi_y:=k; end; dvi_goto(dvi_x-(rule_size[p] div 2), dvi_y); press_set_rule(dvi_y-temp_y, rule_size[p]); end @ @= begin if temp_x; @; dvi_out(pop); @y @; @; @z 160292: Remove another DVI-ness @x @ @= typeset(k); dy:=round(k*slant_unit); dvi_out(z4); dvi_four(-dy); while q>1 do begin typeset(k); dvi_out(z0); decr(q); end @ @= if p>0 then begin incr(k); typeset(k); dy:=round(k*slant_unit); dvi_out(z4); dvi_four(-dy); while p>1 do begin typeset(k); dvi_out(z0); decr(p); end; end @y @ @= typeset(k); dy:=round(k*slant_unit); press_move_y(-dy); while q>1 do begin typeset(k); press_move_y(-dy); decr(q); end @ @= if p>0 then begin incr(k); typeset(k); dy:=round(k*slant_unit); press_move_y(-dy); while p>1 do begin typeset(k); press_move_y(-dy); decr(p); end; end @z 165963: Remove two more |pop|s and also (BUG) remove an unused variable from do_b_label @x @ Here are the procedures for locating the labels, for adding them to the tree and for putting them out. @p procedure do_a_label(@!p:tree_pointer); var @!q:tree_pointer; begin hbox(info[p],label_font,false); {Compute the size of this label} dvi_x:=xx[p]; dvi_y:=yy[p]; case lab_typ[p] of "1","5":top_coords(p); "2","6":left_coords(p); "3","7":right_coords(p); "4","8":bot_coords(p); end; {Only these four cases will be treated by |do_a_label|} q:=dl_tie[p]; oct[q]:=0; {to identify labelled dot for |nearest_dot| routine} tree_ins(p);@/ dvi_goto(xx[p],yy[p]); hbox(info[p],label_font,true); dvi_out(pop); end; @ And here is the second of the two label routines. @p procedure do_b_label(@!p:tree_pointer); label found,exit; var @!q:tree_pointer; k: integer; begin hbox(info[p],label_font,false); {Compute the size of this label} dvi_x:=xx[p]; dvi_y:=yy[p]; @; found:tree_ins(p);@/ q:=dl_tie[p]; oct[q]:=0; {to identify labelled dot for |nearest_dot| routine} dvi_goto(xx[p],yy[p]); hbox(info[p],label_font,true); dvi_out(pop); exit:end; @y @ Here are the procedures for locating the labels, for adding them to the tree and for putting them out. @p procedure do_a_label(@!p:tree_pointer); var @!q:tree_pointer; begin hbox(info[p],label_font,false); {Compute the size of this label} dvi_x:=xx[p]; dvi_y:=yy[p]; case lab_typ[p] of "1","5":top_coords(p); "2","6":left_coords(p); "3","7":right_coords(p); "4","8":bot_coords(p); end; {Only these four cases will be treated by |do_a_label|} q:=dl_tie[p]; oct[q]:=0; {to identify labelled dot for |nearest_dot| routine} tree_ins(p);@/ dvi_goto(xx[p],yy[p]); hbox(info[p],label_font,true); end; @ And here is the second of the two label routines. @p procedure do_b_label(@!p:tree_pointer); label found,exit; var @!q:tree_pointer; begin hbox(info[p],label_font,false); {Compute the size of this label} dvi_x:=xx[p]; dvi_y:=yy[p]; @; found:tree_ins(p);@/ q:=dl_tie[p]; oct[q]:=0; {to identify labelled dot for |nearest_dot| routine} dvi_goto(xx[p],yy[p]); hbox(info[p],label_font,true); exit:end; @z 167240: Fix up dotting @x @p procedure do_dot(@!p:tree_pointer); var @!q:tree_pointer; begin q:=get_avail; if first_dot=0 then first_dot:=q; last_dot:=q; dl_tie[p]:=q; dl_tie[q]:=p; info[q]:=-info[p]; convert(xx[p],yy[p]);@/ xx[q]:=dvi_x; yy[q]:=dvi_y;@/ xx[p]:=xx[q]; yy[p]:=yy[q];@/ xl[q]:=dvi_x-dot_width; xr[q]:=dvi_x+dot_width;@/ yt[q]:=dvi_y-dot_height; yb[q]:=dvi_y+dot_height;@/ tree_ins(q);@/ dvi_goto(xx[q],yy[q]); dvi_out(0); dvi_out(pop); end; @y @p procedure do_dot(@!p:tree_pointer); var @!q:tree_pointer; begin q:=get_avail; if first_dot=0 then first_dot:=q; last_dot:=q; dl_tie[p]:=q; dl_tie[q]:=p; info[q]:=-info[p]; convert(xx[p],yy[p]);@/ xx[q]:=dvi_x; yy[q]:=dvi_y;@/ xx[p]:=xx[q]; yy[p]:=yy[q];@/ xl[q]:=dvi_x-dot_width; xr[q]:=dvi_x+dot_width;@/ yt[q]:=dvi_y-dot_height; yb[q]:=dvi_y+dot_height;@/ tree_ins(q);@/ dvi_goto(xx[q],yy[q]); typeset(0); end; @z 168839: Fix up overflow labelling @x @ @= begin q:=dl_tie[p]; n_l_dot(q); incr(overflow_line); dvi_goto(over_col,overflow_line*thrice_x_height+655360); hbox(info[p],label_font,true); hbox(equals_sign,label_font,true); hbox(-info[q_dot],label_font,true); hbox(plus_sign,label_font,true); dvi_scaled((xx[p]-xx[q_dot])/x_ratio+(yy[p]-yy[q_dot])*fudge_factor); dvi_out(","); dvi_scaled((yy[q_dot]-yy[p])/y_ratio); dvi_out(")"); dvi_out(pop); end @y @ @= begin q:=dl_tie[p]; n_l_dot(q); incr(overflow_line); dvi_goto(over_col,overflow_line*thrice_x_height+655360); hbox(info[p],label_font,true); hbox(equals_sign,label_font,true); hbox(-info[q_dot],label_font,true); hbox(plus_sign,label_font,true); dvi_scaled((xx[p]-xx[q_dot])/x_ratio+(yy[p]-yy[q_dot])*fudge_factor); typeset(","); dvi_scaled((yy[q_dot]-yy[p])/y_ratio); typeset(")"); end @z 169281: Remove a DVI-related module @x @ @= if overflow_line>1 then page_width:=over_col+10000000; {overflow labels are estimated to occupy $10^7\,$sp} if page_width>max_h then max_h:=page_width @y @ (201) @z 171911: Fix up typesetting the pixels @x @= j:=starting_col; loop@+ begin while (j<=finishing_col)and(b[a[j]]=0) do incr(j); if j>finishing_col then goto done; dvi_out(push); @; repeat v:=b[a[j]]; a[j]:=a[j]-c[v]; k:=j; incr(j); while b[a[j]]=v do begin a[j]:=a[j]-c[v]; incr(j); end; k:=j-k; @; until b[a[j]]=0; dvi_out(pop); end; done: @y @= j:=starting_col; loop@+ begin while (j<=finishing_col)and(b[a[j]]=0) do incr(j); if j>finishing_col then goto done; press_push_pos; @; repeat v:=b[a[j]]; a[j]:=a[j]-c[v]; k:=j; incr(j); while b[a[j]]=v do begin a[j]:=a[j]-c[v]; incr(j); end; k:=j-k; @; until b[a[j]]=0; press_pop_pos; end; done: @z 172374: Fix up moving right @x @ @= dvi_out(right4); dvi_four(round(unsc_x_ratio*j+unsc_slant_ratio*y)+delta_x) @y @ @= press_move_x(round(unsc_x_ratio*j+unsc_slant_ratio*y)+delta_x) @z 177578: Remove another |pop| @x dvi_out(pop); @; @y @; @z 177640: Break up the main program into small enough pieces for the Cedar compiler. Also, print out a newline at the very end of the program. @x @* The main program. Now we are ready to put it all together. This is where \.{GFtoDVI} starts, and where it ends. @p begin initialize; {get all variables initialized} @; start_gf; {open the input and output files} @; cur_gf:=get_byte; init_str_ptr:=str_ptr; loop@+ begin @; while (cur_gf>=xxx1)and(cur_gf<=no_op) do @; if cur_gf=post then @; if cur_gf<>boc then if cur_gf<>boc1 then abort('Missing boc!'); @.Missing boc@> @; cur_gf:=get_byte; str_ptr:=init_str_ptr; pool_ptr:=str_start[str_ptr]; end; final_end:end. @y @* The main program. Now we are ready to put it all together. This is where \.{GFtoDVI} starts, and where it ends. @p procedure init_strings; begin @ end; @# procedure process_a_character; begin @ end; @# begin initialize; {get all variables initialized} init_strings; start_gf; {open the input and output files} @; cur_gf:=get_byte; init_str_ptr:=str_ptr; loop@+ begin @; while (cur_gf>=xxx1)and(cur_gf<=no_op) do @; if cur_gf=post then @; if cur_gf<>boc then if cur_gf<>boc1 then abort('Missing boc!'); @.Missing boc@> process_a_character; cur_gf:=get_byte; str_ptr:=init_str_ptr; pool_ptr:=str_start[str_ptr]; end; final_end: print_ln(''); end. @z 179157: Remove preamble production @x dvi_out(pre); dvi_out(dvi_id_byte); {output the preamble} dvi_four(25400000); dvi_four(473628672); {conversion ratio for sp} dvi_four(1000); {magnification factor} dvi_out(k); use_logo:=false; s:=str_start[str_ptr]; for m:=1 to k do dvi_out(str_pool[s+m-1]); @y use_logo:=false; s:=str_start[str_ptr]; @z 179828: Declare externals @x @* System-dependent changes. This section should be replaced, if necessary, by changes to the program that are necessary to make \.{GFtoDVI} 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 @* Declaration of externals for things implemented in Cedar. @ = procedure press_open_file; external; function press_get_font_code(f: internal_font_number): cedar_nat; external; procedure press_set_font(f: internal_font_number); external; procedure press_set_char(ch: eight_bits); external; procedure press_push_pos; external; procedure press_pop_pos; external; procedure press_goto(x, y: scaled); external; procedure press_move_x(x: scaled); external; procedure press_move_y(y: scaled); external; procedure press_set_rule(h, w: scaled); external; procedure press_write_page; external; procedure press_close_file; external; procedure tty_reset(var f: text_file); external; procedure tty_rewrite(var f: text_file); external; procedure byte_file_reset(var f: byte_file); external; procedure get_command_line; external; @ Remember to declare the global boolean used in getting input from the command line. @= command_line_already_gotten:boolean; @ Initialize the variable as well. @= command_line_already_gotten := false; @ Also, declare the type used in storing Press font codes. @= cedar_nat = 0..32767; @z