% omdir.ch: Primitives to deal with multiple-direction text % % This file is part of the Omega projet, which % is based on the web2c distribution of TeX. % % Copyright (c) 1994--2000 John Plaice and Yannis Haralambous % % This library is free software; you can redistribute it and/or % modify it under the terms of the GNU Library General Public % License as published by the Free Software Foundation; either % version 2 of the License, or (at your option) any later version. % % This library is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU % Library General Public License for more details. % % You should have received a copy of the GNU Library General Public % License along with this library; if not, write to the Free Software % Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. % %------------------------- @x [10] m.135 @d hlist_node=0 {|type| of hlist nodes} @d box_node_size=7 {number of words to allocate for a box node} @d width_offset=1 {position of |width| field in a box node} @d depth_offset=2 {position of |depth| field in a box node} @d height_offset=3 {position of |height| field in a box node} @d width(#) == mem[#+width_offset].sc {width of the box, in sp} @d depth(#) == mem[#+depth_offset].sc {depth of the box, in sp} @d height(#) == mem[#+height_offset].sc {height of the box, in sp} @d shift_amount(#) == mem[#+4].sc {repositioning distance, in sp} @d list_offset=5 {position of |list_ptr| field in a box node} @d list_ptr(#) == link(#+list_offset) {beginning of the list inside the box} @d glue_order(#) == subtype(#+list_offset) {applicable order of infinity} @d glue_sign(#) == type(#+list_offset) {stretching or shrinking} @d normal=0 {the most common case when several cases are named} @d stretching = 1 {glue setting applies to the stretch components} @d shrinking = 2 {glue setting applies to the shrink components} @d glue_offset = 6 {position of |glue_set| in a box node} @d glue_set(#) == mem[#+glue_offset].gr {a word of type |glue_ratio| for glue setting} @y @d hlist_node=0 {|type| of hlist nodes} @d box_node_size=8 {number of words to allocate for a box node} @d width_offset=1 {position of |width| field in a box node} @d depth_offset=2 {position of |depth| field in a box node} @d height_offset=3 {position of |height| field in a box node} @d width(#) == mem[#+width_offset].sc {width of the box, in sp} @d depth(#) == mem[#+depth_offset].sc {depth of the box, in sp} @d height(#) == mem[#+height_offset].sc {height of the box, in sp} @d shift_amount(#) == mem[#+4].sc {repositioning distance, in sp} @d list_offset=5 {position of |list_ptr| field in a box node} @d list_ptr(#) == link(#+list_offset) {beginning of the list inside the box} @d glue_order(#) == subtype(#+list_offset) {applicable order of infinity} @d glue_sign(#) == type(#+list_offset) {stretching or shrinking} @d normal=0 {the most common case when several cases are named} @d stretching = 1 {glue setting applies to the stretch components} @d shrinking = 2 {glue setting applies to the shrink components} @d glue_offset = 6 {position of |glue_set| in a box node} @d glue_set(#) == mem[#+glue_offset].gr {a word of type |glue_ratio| for glue setting} @d dir_offset = 7 {position of |box_dir| in a box node} @d box_dir(#) == mem[#+dir_offset].int @z %------------------------- @x [10] m.136 @p function new_null_box:pointer; {creates a new box node} var p:pointer; {the new node} begin p:=get_node(box_node_size); type(p):=hlist_node; subtype(p):=min_quarterword; width(p):=0; depth(p):=0; height(p):=0; shift_amount(p):=0; list_ptr(p):=null; glue_sign(p):=normal; glue_order(p):=normal; set_glue_ratio_zero(glue_set(p)); new_null_box:=p; @y @p function new_null_box:pointer; {creates a new box node} var p:pointer; {the new node} begin p:=get_node(box_node_size); type(p):=hlist_node; subtype(p):=min_quarterword; width(p):=0; depth(p):=0; height(p):=0; shift_amount(p):=0; list_ptr(p):=null; glue_sign(p):=normal; glue_order(p):=normal; set_glue_ratio_zero(glue_set(p)); box_dir(p):=text_direction; new_null_box:=p; @z %------------------------- @x [10] m.138 @d rule_node=2 {|type| of rule nodes} @d rule_node_size=4 {number of words to allocate for a rule node} @d null_flag==-@'10000000000 {$-2^{30}$, signifies a missing item} @d is_running(#) == (#=null_flag) {tests for a running dimension} @y @d rule_node=2 {|type| of rule nodes} @d rule_node_size=5 {number of words to allocate for a rule node} @d null_flag==-@'10000000000 {$-2^{30}$, signifies a missing item} @d is_running(#) == (#=null_flag) {tests for a running dimension} @d rule_dir(#)==info(#+4) @z %------------------------- @x [10] m.139 @p function new_rule:pointer; var p:pointer; {the new node} begin p:=get_node(rule_node_size); type(p):=rule_node; subtype(p):=0; {the |subtype| is not used} width(p):=null_flag; depth(p):=null_flag; height(p):=null_flag; new_rule:=p; end; @y @p function new_rule:pointer; var p:pointer; {the new node} begin p:=get_node(rule_node_size); type(p):=rule_node; subtype(p):=0; {the |subtype| is not used} width(p):=null_flag; depth(p):=null_flag; height(p):=null_flag; rule_dir(p):=-1; new_rule:=p; end; @z %------------------------- @x [10] m.176 procedure print_rule_dimen(@!d:scaled); {prints dimension in rule node} begin if is_running(d) then print_char("*") else print_scaled(d); @.*\relax@> end; @y procedure print_rule_dimen(@!d:scaled); {prints dimension in rule node} begin if is_running(d) then print_char("*") else print_scaled(d); @.*\relax@> end; @# procedure print_dir(d:integer); begin print(dir_names[dir_primary[d]]); print(dir_names[dir_secondary[d]]); print(dir_names[dir_tertiary[d]]); end; @z %------------------------- @x [12] m.184 @ @= begin if type(p)=hlist_node then print_esc("h") else if type(p)=vlist_node then print_esc("v") else print_esc("unset"); print("box("); print_scaled(height(p)); print_char("+"); print_scaled(depth(p)); print(")x"); print_scaled(width(p)); if type(p)=unset_node then @ else begin @; if shift_amount(p)<>0 then begin print(", shifted "); print_scaled(shift_amount(p)); end; end; node_list_display(list_ptr(p)); {recursive call} end @y @ @= begin if type(p)=hlist_node then print_esc("h") else if type(p)=vlist_node then print_esc("v") else print_esc("unset"); print("box("); print_scaled(height(p)); print_char("+"); print_scaled(depth(p)); print(")x"); print_scaled(width(p)); if type(p)=unset_node then @ else begin @; if shift_amount(p)<>0 then begin print(", shifted "); print_scaled(shift_amount(p)); end; print(", direction "); print_dir(box_dir(p)); end; node_list_display(list_ptr(p)); {recursive call} end @z %------------------------- @x [10] m.206 hlist_node,vlist_node,unset_node: begin r:=get_node(box_node_size); mem[r+6]:=mem[p+6]; mem[r+5]:=mem[p+5]; {copy the last two words} @y hlist_node,vlist_node,unset_node: begin r:=get_node(box_node_size); mem[r+7]:=mem[p+7]; mem[r+6]:=mem[p+6]; mem[r+5]:=mem[p+5]; {copy the last three words} @z %------------------------- @x [15] m.209 @d max_internal=register {the largest code that can follow \.{\\the}} @y @d assign_dir=register+1 {(\.{\\pagedir}, \.{\\textdir})} @d max_internal=assign_dir {the largest code that can follow \.{\\the}} @z %------------------------- @x [16] m.212 @!aux_field: memory_word; @y @!aux_field: memory_word; @!dirs_field: halfword; @!math_field: integer; @z %------------------------- @x [16] m.212 @d mode_line==cur_list.ml_field {source file line number at beginning of list} @y @d mode_line==cur_list.ml_field {source file line number at beginning of list} @d dir_save==cur_list.dirs_field {dir stack when a paragraph is interrupted} @d dir_math_save==cur_list.math_field {should begin/end dir nodes be placed around mathematics?} @z %------------------------- @x [16] m.215 prev_graf:=0; shown_mode:=0; @y prev_graf:=0; shown_mode:=0; dir_save:=null; dir_math_save:=false; @z %------------------------- @x [16] m.216 l.4351 @ @p @; @y @ @p @; @ @p @; @z %------------------------- @x [16] m.216 incr(nest_ptr); head:=get_avail; tail:=head; prev_graf:=0; mode_line:=line; @y incr(nest_ptr); head:=get_avail; tail:=head; prev_graf:=0; mode_line:=line; dir_save:=null; dir_math_save:=false; @z %------------------------- @x [16] m.217 free_avail(head); decr(nest_ptr); cur_list:=nest[nest_ptr]; @y free_avail(head); decr(nest_ptr); cur_list:=nest[nest_ptr]; @z %------------------------- @x [17] m.236 @d int_pars=58 {total number of integer parameters} @d count_base=int_base+int_pars {|number_regs| user \.{\\count} registers} @y @d no_local_dirs_code=58 @d level_local_dir_code=59 @d int_pars=61 {total number of integer parameters} @d dir_base=int_base+int_pars @d page_direction_code=0 @d body_direction_code=1 @d par_direction_code=2 @d text_direction_code=3 @d math_direction_code=4 @d dir_pars=5 @d count_base=dir_base+dir_pars {|number_regs| user \.{\\count} registers} @z %------------------------- @x [17] m.238 @d no_local_whatsits==int_par(no_local_whatsits_code) @y @d no_local_whatsits==int_par(no_local_whatsits_code) @d no_local_dirs==int_par(no_local_dirs_code) @d level_local_dir==int_par(level_local_dir_code) @d dir_par(#)==new_eqtb_int(dir_base+#) {a direction parameter} @d page_direction==dir_par(page_direction_code) @d body_direction==dir_par(body_direction_code) @d par_direction==dir_par(par_direction_code) @d text_direction==dir_par(text_direction_code) @d math_direction==dir_par(math_direction_code) @z %------------------------- @x [17] m.240 set_new_eqtb_int(int_base+end_line_char_code,carriage_return); @y set_new_eqtb_int(int_base+end_line_char_code,carriage_return); set_new_eqtb_int(int_base+level_local_dir_code,level_one); @z %------------------------- @x [17] m.247 @d dimen_pars=21 {total number of dimension parameters} @y @d page_width_code=21 @d page_height_code=22 @d page_right_offset_code=23 @d page_bottom_offset_code=24 @d dimen_pars=25 {total number of dimension parameters} @z %------------------------- @x [17] m.247 @d emergency_stretch==dimen_par(emergency_stretch_code) @y @d emergency_stretch==dimen_par(emergency_stretch_code) @d page_width==dimen_par(page_width_code) @d page_height==dimen_par(page_height_code) @d page_right_offset==dimen_par(page_right_offset_code) @d page_bottom_offset==dimen_par(page_bottom_offset_code) @z %------------------------- @x [26] m.410 @d int_val=0 {integer values} @d dimen_val=1 {dimension values} @d glue_val=2 {glue specifications} @d mu_val=3 {math glue specifications} @d ident_val=4 {font identifier} @d tok_val=5 {token lists} @= @!cur_val:integer; {value returned by numeric scanners} @!cur_val_level:int_val..tok_val; {the ``level'' of this value} @y @d int_val=0 {integer values} @d dimen_val=1 {dimension values} @d glue_val=2 {glue specifications} @d mu_val=3 {math glue specifications} @d dir_val=4 {directions} @d ident_val=5 {font identifier} @d tok_val=6 {token lists} @= @!cur_val:integer; {value returned by numeric scanners} @!cur_val1:integer; {delcodes are now 51 digits} @!cur_val_level:int_val..dir_val; {the ``level'' of this value} @z %------------------------- @x [26] m.413 assign_int: scanned_result(new_eqtb_int(m))(int_val); @y assign_int: scanned_result(new_eqtb_int(m))(int_val); assign_dir: scanned_result(new_eqtb_int(m))(dir_val); @z %------------------------- @x [26] m.437 @ @= procedure scan_eight_bit_int; @y @ @d dir_T=0 @d dir_L=1 @d dir_B=2 @d dir_R=3 @d dir_eq_end(#)==(#) @d dir_eq(#)==(#)=dir_eq_end @d dir_ne_end(#)==(#) @d dir_ne(#)==(#)<>dir_ne_end @d dir_opposite_end(#)==((#) mod 4) @d dir_opposite(#)==(((#)+2) mod 4)=dir_opposite_end @d dir_parallel_end(#)==((#) mod 2) @d dir_parallel(#)==((#) mod 2)=dir_parallel_end @d dir_orthogonal_end(#)==(# mod 2) @d dir_orthogonal(#)==((#) mod 2)<>dir_orthogonal_end @d dir_next_end(#)==((#) mod 4) @d dir_next(#)==(((#)+3) mod 4)=dir_next_end @d dir_prev_end(#)==((#) mod 4) @d dir_prev(#)==(((#)+1) mod 4)=dir_prev_end {box directions} @d dir_TL_=0 @d dir_TR_=1 @d dir_LT_=2 @d dir_LB_=3 @d dir_BL_=4 @d dir_BR_=5 @d dir_RT_=6 @d dir_RB_=7 {font directions} @d dir__LT= 0 @d dir__LL= 1 @d dir__LB= 2 @d dir__LR= 3 @d dir__RT= 4 @d dir__RL= 5 @d dir__RB= 6 @d dir__RR= 7 @d dir__TT= 8 @d dir__TL= 9 @d dir__TB=10 @d dir__TR=11 @d dir__BT=12 @d dir__BL=13 @d dir__BB=14 @d dir__BR=15 @d is_mirrored(#)==dir_opposite(dir_primary[#])(dir_tertiary[#]) @d is_rotated(#)==dir_parallel(dir_secondary[#])(dir_tertiary[#]) @d font_direction(#)==(# mod 16) @d box_direction(#)==(# div 4) @d scan_single_dir(#)==begin if scan_keyword("T") then #:=dir_T else if scan_keyword("L") then #:=dir_L else if scan_keyword("B") then #:=dir_B else if scan_keyword("R") then #:=dir_R else begin print_err("Bad direction"); cur_val:=0; goto exit; end end @= procedure scan_dir; var d1,d2,d3: integer; begin get_x_token; if cur_cmd=assign_dir then begin cur_val:=new_eqtb_int(cur_chr); goto exit; end else back_input; scan_single_dir(d1); scan_single_dir(d2); if dir_parallel(d1)(d2) then begin print_err("Bad direction"); cur_val:=0; goto exit; end; scan_single_dir(d3); cur_val:=d1*8+dir_rearrange[d2]*4+d3; exit: end; @ @= procedure scan_eight_bit_int; @z %------------------------- @x [27] m.463 @p function scan_rule_spec:pointer; label reswitch; var q:pointer; {the rule node being created} begin q:=new_rule; {|width|, |depth|, and |height| all equal |null_flag| now} if cur_cmd=vrule then width(q):=default_rule else begin height(q):=default_rule; depth(q):=0; end; @y @p function scan_rule_spec:pointer; label reswitch; var q:pointer; {the rule node being created} begin q:=new_rule; {|width|, |depth|, and |height| all equal |null_flag| now} if cur_cmd=vrule then begin width(q):=default_rule; rule_dir(q):=body_direction; end else begin height(q):=default_rule; depth(q):=0; rule_dir(q):=text_direction; end; @z %------------------------- @x [27] m.465 int_val:print_int(cur_val); @y int_val:print_int(cur_val); dir_val:print_dir(cur_val); @z %------------------------- @x [30] m.550 @d offset_false_bchar=offset_bchar+1 @d offset_ivalues_start=offset_false_bchar+1 @y @d offset_false_bchar=offset_bchar+1 @d offset_natural_dir=offset_false_bchar+1 @d offset_ivalues_start=offset_natural_dir+1 @z %------------------------- @x [30] m.550 @d font_false_bchar(#)==font_info(#)(offset_false_bchar).int @y @d font_false_bchar(#)==font_info(#)(offset_false_bchar).int @d font_natural_dir(#)==font_info(#)(offset_natural_dir).int @z %------------------------- @x [30] m.560 @p function read_font_info(@!u:pointer;@!nom,@!aire:str_number; @!s:scaled;offset:quarterword):internal_font_number; {input a \.{TFM} file} @y @p function read_font_info(@!u:pointer;@!nom,@!aire:str_number; @!s:scaled;offset:quarterword;natural_dir:integer):internal_font_number; {input a \.{TFM} file} @z %------------------------- @x [30] m.560 font_offset(f):=offset; @y font_offset(f):=offset; font_natural_dir(f):=natural_dir; @z %------------------------- @x [31] m.586 @d set_rule=132 {typeset a rule and move right} @y @d set_rule=132 {typeset a rule and move right} @d put1==133 {typeset a character without moving} @z %------------------------- @x [31] m.586 @d right1=143 {move right} @y @d right1==143 {move right} @d right4==146 {move right, 4 bytes} @z %------------------------- @x [31] m.586 @d down1=157 {move down} @y @d down1=157 {move down} @d down4=160 {move down, 4 bytes} @z %------------------------- @x [32] m.607 @p procedure movement(@!w:scaled;@!o:eight_bits); label exit,found,not_found,2,1; var mstate:small_number; {have we seen a |y| or |z|?} @!p,@!q:pointer; {current and top nodes on the stack} @!k:integer; {index into |dvi_buf|, modulo |dvi_buf_size|} begin q:=get_node(movement_node_size); {new node for the top of the stack} width(q):=w; location(q):=dvi_offset+dvi_ptr; if o=down1 then begin link(q):=down_ptr; down_ptr:=q; end else begin link(q):=right_ptr; right_ptr:=q; end; @; @; found: @; exit:end; @y @d dvi_set(#)==oval:=#-font_offset(f); ocmd:=set1; out_cmd @d dvi_put(#)==oval:=#-font_offset(f); ocmd:=put1; out_cmd @d dvi_set_rule_end(#)==dvi_four(#) @d dvi_set_rule(#)==dvi_out(set_rule); dvi_four(#); dvi_set_rule_end @d dvi_put_rule_end(#)==dvi_four(#) @d dvi_put_rule(#)==dvi_out(put_rule); dvi_four(#); dvi_put_rule_end @d dvi_right(#)==dvi_out(right4); dvi_four(#); @d dvi_left(#)==dvi_out(right4); dvi_four(-#); @d dvi_down(#)==dvi_out(down4); dvi_four(#); @d dvi_up(#)==dvi_out(down4); dvi_four(-#); @p procedure movement(@!w:scaled;@!o:eight_bits); label exit,found,not_found,2,1; var mstate:small_number; {have we seen a |y| or |z|?} @!p,@!q:pointer; {current and top nodes on the stack} @!k:integer; {index into |dvi_buf|, modulo |dvi_buf_size|} begin case box_direction(dvi_direction) of dir_TL_: begin end; dir_TR_: begin if o=right1 then negate(w); end; dir_LT_: begin if o=right1 then o:=down1 else o:=right1; end; dir_LB_: begin if o=right1 then begin o:=down1; negate(w); end else o:=right1; end; dir_BL_: begin if o=down1 then negate(w); end; dir_BR_: begin negate(w); end; dir_RT_: begin if o=right1 then o:=down1 else begin o:=right1; negate(w); end; end; dir_RB_: begin if o=right1 then o:=down1 else o:=right1; negate(w); end; end; if false then begin q:=get_node(movement_node_size); {new node for the top of the stack} width(q):=w; location(q):=dvi_offset+dvi_ptr; if o=down1 then begin link(q):=down_ptr; down_ptr:=q; end else begin link(q):=right_ptr; right_ptr:=q; end; @; end; @; found: @; exit:end; @z %------------------------- @x [32] m.610 info(q):=yz_OK; @y @z %------------------------- @x [32] m.617 dvi_h:=0; dvi_v:=0; cur_h:=h_offset; dvi_f:=null_font; @y dvi_h:=0; dvi_v:=0; cur_h:=0; cur_v:=0; dvi_f:=null_font; @z %------------------------- @x [32] m.619 procedure hlist_out; {output an |hlist_node| box} label reswitch, move_past, fin_rule, next_p; var base_line: scaled; {the baseline coordinate for this box} @y procedure hlist_out; {output an |hlist_node| box} label reswitch, move_past, fin_rule, next_p; var base_line: scaled; {the baseline coordinate for this box} c_wd,c_ht,c_dp: scaled; {the real width, height and depth of the character} c_htdp: quarterword; {height-depth entry in |char_info|} c_info: four_quarters; {|char_info| entry} edge_v: scaled; edge_h: scaled; effective_horizontal: scaled; basepoint_horizontal: scaled; basepoint_vertical: scaled; saving_h: scaled; saving_v: scaled; save_direction: integer; dir_tmp,dir_ptr:pointer; dvi_dir_h,dvi_dir_ptr,dvi_temp_ptr:integer; @z %------------------------- @x [32] m.619 incr(cur_s); if cur_s>0 then dvi_out(push); if cur_s>max_push then max_push:=cur_s; save_loc:=dvi_offset+dvi_ptr; base_line:=cur_v; left_edge:=cur_h; while p<>null do @; prune_movements(save_loc); if cur_s>0 then dvi_pop(save_loc); decr(cur_s); @y save_direction:=dvi_direction; dvi_direction:=box_dir(this_box); @; saving_h:=dvi_h; saving_v:=dvi_v; incr(cur_s); if cur_s>0 then dvi_out(push); if cur_s>max_push then max_push:=cur_s; save_loc:=dvi_offset+dvi_ptr; base_line:=cur_v; left_edge:=cur_h; while p<>null do @; cur_h:=saving_h; cur_v:=saving_v; synch_h; synch_v; prune_movements(save_loc); if cur_s>0 then dvi_pop(save_loc); decr(cur_s); dvi_direction:=save_direction; @; @z %------------------------- @x [32] m.620 oval:=c-font_offset(f); ocmd:=set1; out_cmd;@/ cur_h:=cur_h+char_width(f)(char_info(f)(c)); @y c_info:=char_info(f)(c); c_htdp:=height_depth(c_info); if is_rotated(dvi_direction) then begin c_ht:=char_width(f)(c_info) div 2; c_wd:=char_height(f)(c_htdp)+char_depth(f)(c_htdp); end else begin c_ht:=char_height(f)(c_htdp); c_dp:=char_depth(f)(c_htdp); c_wd:=char_width(f)(c_info); end; cur_h:=cur_h+c_wd; if (font_natural_dir(f)<>-1) then case font_direction(dvi_direction) of dir__LT,dir__LB: begin dvi_set(c); end; dir__RT,dir__RB: begin dvi_put(c); dvi_left(c_wd); end; dir__TL,dir__TR: begin dvi_put(c); dvi_down(c_wd); end; dir__BL,dir__BR: begin dvi_put(c); dvi_up(c_wd); end; dir__LL,dir__LR: begin dvi_put(c); dvi_right(c_wd); end; dir__RL,dir__RR: begin dvi_put(c); dvi_left(c_wd); end; dir__TT,dir__TB: begin dvi_put(c); dvi_down(c_wd); end; dir__BT,dir__BB: begin dvi_put(c); dvi_up(c_wd); end; end else case font_direction(dvi_direction) of dir__LT: begin dvi_set(c); end; dir__LB: begin dvi_down(c_ht); dvi_set(c); dvi_up(c_ht); end; dir__RT: begin dvi_left(c_wd); dvi_put(c); end; dir__RB: begin dvi_left(c_wd); dvi_down(c_ht); dvi_put(c); dvi_up(c_ht); end; dir__TL: begin dvi_down(c_wd); dvi_left(c_ht); dvi_put(c); dvi_right(c_ht); end; dir__TR: begin dvi_down(c_wd); dvi_left(c_dp); dvi_put(c); dvi_right(c_dp); end; dir__BL: begin dvi_left(c_ht); dvi_put(c); dvi_right(c_ht); dvi_up(c_wd); end; dir__BR: begin dvi_left(c_dp); dvi_put(c); dvi_right(c_dp); dvi_up(c_wd); end; dir__LL,dir__LR: begin dvi_down(c_ht); dvi_put(c); dvi_up(c_ht); dvi_right(c_wd); end; dir__RL,dir__RR: begin dvi_left(c_wd); dvi_down(c_ht); dvi_put(c); dvi_up(c_ht); end; dir__TT,dir__TB: begin dvi_down(c_wd); dvi_left(c_ht); dvi_put(c); dvi_right(c_ht); end; dir__BT,dir__BB: begin dvi_left(c_ht); dvi_put(c); dvi_right(c_ht); dvi_up(c_wd); end; end; @z %------------------------- @x [32] m.622 rule_node: begin rule_ht:=height(p); rule_dp:=depth(p); rule_wd:=width(p); goto fin_rule; end; @y rule_node: begin if not (dir_orthogonal(dir_primary[rule_dir(p)])(dir_primary[dvi_direction])) then begin rule_ht:=height(p); rule_dp:=depth(p); rule_wd:=width(p); end else begin rule_ht:=width(p) div 2; rule_dp:=width(p) div 2; rule_wd:=height(p)+depth(p); end; goto fin_rule; end; @z %------------------------- @x [32] m.623 if list_ptr(p)=null then cur_h:=cur_h+width(p) else begin save_h:=dvi_h; save_v:=dvi_v; cur_v:=base_line+shift_amount(p); {shift the box down} temp_ptr:=p; edge:=cur_h; if type(p)=vlist_node then vlist_out@+else hlist_out; dvi_h:=save_h; dvi_v:=save_v; cur_h:=edge+width(p); cur_v:=base_line; end @y begin if not (dir_orthogonal(dir_primary[box_dir(p)])(dir_primary[dvi_direction])) then begin effective_horizontal:=width(p); basepoint_vertical:=0; if dir_opposite(dir_secondary[box_dir(p)])(dir_secondary[dvi_direction]) then basepoint_horizontal:=width(p) else basepoint_horizontal:=0; end else begin effective_horizontal:=height(p)+depth(p); if not (is_mirrored(box_dir(p))) then if dir_eq(dir_primary[box_dir(p)])(dir_secondary[dvi_direction]) then basepoint_horizontal:=height(p) else basepoint_horizontal:=depth(p) else if dir_eq(dir_primary[box_dir(p)])(dir_secondary[dvi_direction]) then basepoint_horizontal:=depth(p) else basepoint_horizontal:=height(p); if dir_eq(dir_secondary[box_dir(p)])(dir_primary[dvi_direction]) then basepoint_vertical:= -(width(p) div 2) else basepoint_vertical:= (width(p) div 2); end; if not (is_mirrored(dvi_direction)) then basepoint_vertical := basepoint_vertical + shift_amount(p) {shift the box `down'} else basepoint_vertical := basepoint_vertical - shift_amount(p); {shift the box `up'} if list_ptr(p)=null then cur_h:=cur_h + effective_horizontal else begin temp_ptr:=p; edge:=cur_h; cur_h:=cur_h + basepoint_horizontal; edge_v:=cur_v; cur_v:=base_line + basepoint_vertical; synch_h; synch_v; save_h:=dvi_h; save_v:=dvi_v; if type(p)=vlist_node then vlist_out@+else hlist_out; dvi_h:=save_h; dvi_v:=save_v; cur_h:=edge+effective_horizontal; cur_v:=base_line; end end @z %------------------------- @x [32] m.624 dvi_out(set_rule); dvi_four(rule_ht); dvi_four(rule_wd); @y case font_direction(dvi_direction) of dir__LT: begin dvi_set_rule(rule_ht)(rule_wd); end; dir__LB: begin dvi_down(rule_ht); dvi_set_rule(rule_ht)(rule_wd); dvi_up(rule_ht); end; dir__RT: begin dvi_left(rule_wd); dvi_put_rule(rule_ht)(rule_wd); end; dir__RB: begin dvi_left(rule_wd); dvi_down(rule_ht); dvi_put_rule(rule_ht)(rule_wd); dvi_up(rule_ht); end; dir__TL: begin dvi_down(rule_wd); dvi_left(rule_ht); dvi_set_rule(rule_wd)(rule_ht); end; dir__TR: begin dvi_down(rule_wd); dvi_put_rule(rule_wd)(rule_ht); end; dir__BL: begin dvi_left(rule_ht); dvi_set_rule(rule_wd)(rule_ht); dvi_up(rule_wd); end; dir__BR: begin dvi_put_rule(rule_wd)(rule_ht); dvi_up(rule_wd); end; end; @z %------------------------- @x [32] m.626 leader_wd:=width(leader_box); @y if not (dir_orthogonal(dir_primary[box_dir(leader_box)])(dir_primary[dvi_direction])) then leader_wd:=width(leader_box) else leader_wd:=height(leader_box)+depth(leader_box); @z ------------------------- @x [32] m.628 @= begin cur_v:=base_line+shift_amount(leader_box); synch_v; save_v:=dvi_v;@/ synch_h; save_h:=dvi_h; temp_ptr:=leader_box; outer_doing_leaders:=doing_leaders; doing_leaders:=true; if type(leader_box)=vlist_node then vlist_out@+else hlist_out; doing_leaders:=outer_doing_leaders; dvi_v:=save_v; dvi_h:=save_h; cur_v:=base_line; cur_h:=save_h+leader_wd+lx; end @y @= begin if not (dir_orthogonal(dir_primary[box_dir(leader_box)])(dir_primary[dvi_direction])) then begin basepoint_vertical:=0; if dir_opposite(dir_secondary[box_dir(leader_box)])(dir_secondary[dvi_direction]) then basepoint_horizontal:=width(leader_box) else basepoint_horizontal:=0; end else begin if not (is_mirrored(box_dir(leader_box))) then if dir_eq(dir_primary[box_dir(leader_box)])(dir_secondary[dvi_direction]) then basepoint_horizontal:=height(leader_box) else basepoint_horizontal:=depth(leader_box) else if dir_eq(dir_primary[box_dir(leader_box)])(dir_secondary[dvi_direction]) then basepoint_horizontal:=depth(leader_box) else basepoint_horizontal:=height(leader_box); if dir_eq(dir_secondary[box_dir(leader_box)])(dir_primary[dvi_direction]) then basepoint_vertical:= -(width(leader_box) div 2) else basepoint_vertical:= (width(leader_box) div 2); end; if not (is_mirrored(dvi_direction)) then basepoint_vertical := basepoint_vertical + shift_amount(leader_box) {shift the box `down'} else basepoint_vertical := basepoint_vertical - shift_amount(leader_box); {shift the box `up'} temp_ptr:=leader_box; edge_h:=cur_h; cur_h:=cur_h + basepoint_horizontal; edge_v:=cur_v; cur_v:=base_line + basepoint_vertical; synch_h; synch_v; save_h:=dvi_h; save_v:=dvi_v; outer_doing_leaders:=doing_leaders; doing_leaders:=true; if type(leader_box)=vlist_node then vlist_out@+else hlist_out; doing_leaders:=outer_doing_leaders; dvi_h:=save_h; dvi_v:=save_v; cur_h:=edge_h+leader_wd+lx; cur_v:=base_line; end @z %------------------------- @x [32] m.629 @!glue_temp:real; {glue value before rounding} @!cur_glue:real; {glue seen so far} @!cur_g:scaled; {rounded equivalent of |cur_glue| times the glue ratio} begin cur_g:=0; cur_glue:=float_constant(0); this_box:=temp_ptr; g_order:=glue_order(this_box); g_sign:=glue_sign(this_box); p:=list_ptr(this_box); incr(cur_s); if cur_s>0 then dvi_out(push); if cur_s>max_push then max_push:=cur_s; save_loc:=dvi_offset+dvi_ptr; left_edge:=cur_h; cur_v:=cur_v-height(this_box); top_edge:=cur_v; while p<>null do @; prune_movements(save_loc); if cur_s>0 then dvi_pop(save_loc); decr(cur_s); @y @!glue_temp:real; {glue value before rounding} @!cur_glue:real; {glue seen so far} @!cur_g:scaled; {rounded equivalent of |cur_glue| times the glue ratio} @!save_direction: integer; @!effective_vertical: scaled; @!basepoint_horizontal: scaled; @!basepoint_vertical: scaled; @!edge_v: scaled; @!saving_v: scaled; @!saving_h: scaled; begin cur_g:=0; cur_glue:=float_constant(0); this_box:=temp_ptr; g_order:=glue_order(this_box); g_sign:=glue_sign(this_box); p:=list_ptr(this_box); saving_v:=dvi_v; saving_h:=dvi_h; save_direction:=dvi_direction; dvi_direction:=box_dir(this_box); incr(cur_s); if cur_s>0 then dvi_out(push); if cur_s>max_push then max_push:=cur_s; save_loc:=dvi_offset+dvi_ptr; left_edge:=cur_h; cur_v:=cur_v-height(this_box); top_edge:=cur_v; while p<>null do @; cur_v:=saving_v; cur_h:=saving_h; synch_v; synch_h; prune_movements(save_loc); if cur_s>0 then dvi_pop(save_loc); decr(cur_s); dvi_direction:=save_direction; @z %------------------------- @x [32] m.631 rule_node: begin rule_ht:=height(p); rule_dp:=depth(p); rule_wd:=width(p); goto fin_rule; end; @y rule_node: begin if not (dir_orthogonal(dir_primary[rule_dir(p)])(dir_primary[dvi_direction])) then begin rule_ht:=height(p); rule_dp:=depth(p); rule_wd:=width(p); end else begin rule_ht:=width(p) div 2; rule_dp:=width(p) div 2; rule_wd:=height(p)+depth(p); end; goto fin_rule; end; @z %------------------------- @x [32] m.632 @= if list_ptr(p)=null then cur_v:=cur_v+height(p)+depth(p) else begin cur_v:=cur_v+height(p); synch_v; save_h:=dvi_h; save_v:=dvi_v; cur_h:=left_edge+shift_amount(p); {shift the box right} temp_ptr:=p; if type(p)=vlist_node then vlist_out@+else hlist_out; dvi_h:=save_h; dvi_v:=save_v; cur_v:=save_v+depth(p); cur_h:=left_edge; end @y @= begin if not (dir_orthogonal(dir_primary[box_dir(p)])(dir_primary[dvi_direction])) then begin effective_vertical:=height(p)+depth(p); if (type(p)=hlist_node) and (is_mirrored(box_dir(p))) then basepoint_vertical:=depth(p) else basepoint_vertical:=height(p); if dir_opposite(dir_secondary[box_dir(p)])(dir_secondary[dvi_direction]) then basepoint_horizontal:=width(p) else basepoint_horizontal:=0; end else begin effective_vertical:=width(p); if not (is_mirrored(box_dir(p))) then if dir_eq(dir_primary[box_dir(p)])(dir_secondary[dvi_direction]) then basepoint_horizontal:=height(p) else basepoint_horizontal:=depth(p) else if dir_eq(dir_primary[box_dir(p)])(dir_secondary[dvi_direction]) then basepoint_horizontal:=depth(p) else basepoint_horizontal:=height(p); if dir_eq(dir_secondary[box_dir(p)])(dir_primary[dvi_direction]) then basepoint_vertical:=0 else basepoint_vertical:=width(p); end; basepoint_horizontal := basepoint_horizontal + shift_amount(p); {shift the box `right'} if list_ptr(p)=null then begin cur_v:=cur_v+effective_vertical; end else begin synch_h; synch_v; edge_v:=cur_v; cur_h:=left_edge + basepoint_horizontal; cur_v:=cur_v + basepoint_vertical; synch_h; synch_v; save_h:=dvi_h; save_v:=dvi_v; temp_ptr:=p; if type(p)=vlist_node then vlist_out@+else hlist_out; dvi_h:=save_h; dvi_v:=save_v; cur_h:=left_edge; cur_v:=edge_v + effective_vertical; end end @z %------------------------- @x [32] m.633 dvi_out(put_rule); dvi_four(rule_ht); dvi_four(rule_wd); @y case font_direction(dvi_direction) of dir__LT: begin dvi_put_rule(rule_ht)(rule_wd); end; dir__LB: begin dvi_down(rule_ht); dvi_put_rule(rule_ht)(rule_wd); dvi_up(rule_ht); end; dir__RT: begin dvi_left(rule_wd); dvi_set_rule(rule_ht)(rule_wd); end; dir__RB: begin dvi_down(rule_ht); dvi_left(rule_wd); dvi_set_rule(rule_ht)(rule_wd); dvi_up(rule_ht); end; dir__TL: begin dvi_down(rule_wd); dvi_left(rule_ht); dvi_set_rule(rule_wd)(rule_ht); dvi_up(rule_wd); end; dir__TR: begin dvi_down(rule_wd); dvi_put_rule(rule_wd)(rule_ht); dvi_up(rule_wd); end; dir__BL: begin dvi_left(rule_ht); dvi_set_rule(rule_wd)(rule_ht); end; dir__BR: begin dvi_put_rule(rule_wd)(rule_ht); end; end; @z %------------------------- @x [32] m.635 leader_ht:=height(leader_box)+depth(leader_box); @y if not (dir_orthogonal(dir_primary[box_dir(leader_box)])(dir_primary[dvi_direction])) then leader_ht:=height(leader_box)+depth(leader_box) else leader_ht:=width(leader_box); @z %------------------------- @x [32] m.637 @= begin cur_h:=left_edge+shift_amount(leader_box); synch_h; save_h:=dvi_h;@/ cur_v:=cur_v+height(leader_box); synch_v; save_v:=dvi_v; temp_ptr:=leader_box; outer_doing_leaders:=doing_leaders; doing_leaders:=true; if type(leader_box)=vlist_node then vlist_out@+else hlist_out; doing_leaders:=outer_doing_leaders; dvi_v:=save_v; dvi_h:=save_h; cur_h:=left_edge; cur_v:=save_v-height(leader_box)+leader_ht+lx; end @y @= begin if not (dir_orthogonal(dir_primary[box_dir(leader_box)])(dir_primary[dvi_direction])) then begin effective_vertical:=height(leader_box)+depth(leader_box); if (type(leader_box)=hlist_node) and (is_mirrored(box_dir(leader_box))) then basepoint_vertical:=depth(leader_box) else basepoint_vertical:=height(leader_box); if dir_opposite(dir_secondary[box_dir(leader_box)])(dir_secondary[dvi_direction]) then basepoint_horizontal:=width(leader_box) else basepoint_horizontal:=0; end else begin effective_vertical:=width(leader_box); if not (is_mirrored(box_dir(leader_box))) then if dir_eq(dir_primary[box_dir(leader_box)])(dir_secondary[dvi_direction]) then basepoint_horizontal:=height(leader_box) else basepoint_horizontal:=depth(leader_box) else if dir_eq(dir_primary[box_dir(leader_box)])(dir_secondary[dvi_direction]) then basepoint_horizontal:=depth(leader_box) else basepoint_horizontal:=height(leader_box); if dir_eq(dir_secondary[box_dir(leader_box)])(dir_primary[dvi_direction]) then basepoint_vertical:= width(leader_box) else basepoint_vertical:= 0; end; basepoint_horizontal := basepoint_horizontal + shift_amount(leader_box); {shift the box `right'} temp_ptr:=leader_box; cur_h:=left_edge + basepoint_horizontal; edge_v:=cur_v ; cur_v:=cur_v + basepoint_vertical; synch_h; synch_v; save_h:=dvi_h; save_v:=dvi_v; outer_doing_leaders:=doing_leaders; doing_leaders:=true; if type(leader_box)=vlist_node then vlist_out@+else hlist_out; doing_leaders:=outer_doing_leaders; dvi_h:=save_h; dvi_v:=save_v; cur_h:=left_edge; cur_v:=edge_v+leader_ht+lx; end @z %------------------------- @x [32] m.640 cur_v:=height(p)+v_offset; temp_ptr:=p; if type(p)=vlist_node then vlist_out@+else hlist_out; @y dvi_direction:=page_direction; case box_direction(dvi_direction) of dir_TL_,dir_LT_: begin end; dir_TR_,dir_RT_: begin dvi_right(page_right_offset); end; dir_RB_,dir_BR_: begin dvi_right(page_right_offset); dvi_down(page_bottom_offset); end; dir_BL_,dir_LB_: begin dvi_down(page_bottom_offset); end; end; cur_h:=h_offset; cur_v:=height(p)+v_offset; case box_direction(dvi_direction) of dir_TL_: begin dvi_down(cur_v); dvi_right(cur_h); end; dir_TR_: begin dvi_down(cur_v); dvi_right(-cur_h); end; dir_LT_: begin dvi_right(cur_v); dvi_down(cur_h); end; dir_LB_: begin dvi_right(cur_v); dvi_down(-cur_h); end; dir_BL_: begin dvi_down(-cur_v); dvi_right(cur_h); end; dir_BR_: begin dvi_down(-cur_v); dvi_right(-cur_h); end; dir_RT_: begin dvi_right(-cur_v); dvi_down(cur_h); end; dir_RB_: begin dvi_right(-cur_v); dvi_down(-cur_h); end; end; dvi_h:=cur_h; dvi_v:=cur_v; temp_ptr:=p; if type(p)=vlist_node then vlist_out@+else hlist_out; @z %------------------------- @x [33] m.644 @d exactly=0 {a box dimension is pre-specified} @d additional=1 {a box dimension is increased from the natural one} @d natural==0,additional {shorthand for parameters to |hpack| and |vpack|} @y @d exactly=0 {a box dimension is pre-specified} @d additional=1 {a box dimension is increased from the natural one} @d natural==0,additional {shorthand for parameters to |hpack| and |vpack|} @= pack_direction:integer; spec_direction:integer; @z %------------------------- @x [33] m.645 @p procedure scan_spec(@!c:group_code;@!three_codes:boolean); {scans a box specification and left brace} label found; var @!s:integer; {temporarily saved value} @!spec_code:exactly..additional; begin if three_codes then s:=saved(0); if scan_keyword("to") then spec_code:=exactly @.to@> else if scan_keyword("spread") then spec_code:=additional @.spread@> else begin spec_code:=additional; cur_val:=0; goto found; end; scan_normal_dimen; found: if three_codes then begin saved(0):=s; incr(save_ptr); end; saved(0):=spec_code; saved(1):=cur_val; save_ptr:=save_ptr+2; new_save_level(c); scan_left_brace; end; @y @p procedure scan_spec(@!c:group_code;@!three_codes:boolean); {scans a box specification and left brace} label found; var @!s:integer; {temporarily saved value} @!spec_code:exactly..additional; begin if three_codes then s:=saved(0); if (c<>align_group) and (c<>vcenter_group) then begin if scan_keyword("dir") then begin scan_dir; spec_direction:=cur_val; end; end; if scan_keyword("to") then spec_code:=exactly @.to@> else if scan_keyword("spread") then spec_code:=additional @.spread@> else begin spec_code:=additional; cur_val:=0; goto found; end; scan_normal_dimen; found: if three_codes then begin saved(0):=s; incr(save_ptr); end; saved(0):=spec_code; saved(1):=cur_val; if (c<>align_group) and (c<>vcenter_group) then begin saved(2):=spec_direction; @; save_ptr:=save_ptr+4; new_save_level(c); scan_left_brace; eq_word_define(dir_base+body_direction_code,spec_direction); eq_word_define(dir_base+par_direction_code,spec_direction); eq_word_define(dir_base+text_direction_code,spec_direction); eq_word_define(int_base+level_local_dir_code,cur_level); end else begin save_ptr:=save_ptr+2; new_save_level(c); scan_left_brace; end; spec_direction:=-1; end; @z %------------------------- @x [33] m.649 @p function hpack(@!p:pointer;@!w:scaled;@!m:small_number):pointer; label reswitch, common_ending, exit; var r:pointer; {the box node that will be returned} @!q:pointer; {trails behind |p|} @!h,@!d,@!x:scaled; {height, depth, and natural width} @!s:scaled; {shift amount} @!g:pointer; {points to a glue specification} @!o:glue_ord; {order of infinity} @!f:internal_font_number; {the font in a |char_node|} @!i:four_quarters; {font information about a |char_node|} @!hd:eight_bits; {height and depth indices for a character} begin last_badness:=0; r:=get_node(box_node_size); type(r):=hlist_node; @y @p function hpack(@!p:pointer;@!w:scaled;@!m:small_number):pointer; label reswitch, common_ending, exit; var r:pointer; {the box node that will be returned} @!q:pointer; {trails behind |p|} @!h,@!d,@!x:scaled; {height, depth, and natural width} @!s:scaled; {shift amount} @!g:pointer; {points to a glue specification} @!o:glue_ord; {order of infinity} @!f:internal_font_number; {the font in a |char_node|} @!i:four_quarters; {font information about a |char_node|} @!hd:eight_bits; {height and depth indices for a character} @!dir_tmp,@!dir_ptr:pointer; {for managing the direction stack} @!hpack_dir:integer; {the current direction} begin last_badness:=0; r:=get_node(box_node_size); type(r):=hlist_node; if pack_direction=-1 then box_dir(r):=text_direction else begin box_dir(r):=pack_direction; pack_direction:=-1; end; hpack_dir:=box_dir(r); @; @z %------------------------- @x [33] m.649 exit: hpack:=r; @y exit: @; hpack:=r; @z %------------------------- @x [33] m.653 @= begin x:=x+width(p); if type(p)>=rule_node then s:=0 @+else s:=shift_amount(p); if height(p)-s>h then h:=height(p)-s; if depth(p)+s>d then d:=depth(p)+s; end @y @= begin if (type(p)=hlist_node) or (type(p)=vlist_node) then begin if dir_orthogonal(dir_primary[box_dir(p)])(dir_primary[hpack_dir]) then begin x:=x+height(p)+depth(p); s:=shift_amount(p); if (width(p) div 2)-s>h then h:=(width(p) div 2)-s; if (width(p) div 2)+s>d then d:=(width(p) div 2)+s; end else if (type(p)=hlist_node) and (is_mirrored(hpack_dir)) then begin x:=x+width(p); s:=shift_amount(p); if depth(p)-s>h then h:=depth(p)-s; if height(p)+s>d then d:=height(p)+s; end else begin x:=x+width(p); s:=shift_amount(p); if height(p)-s>h then h:=height(p)-s; if depth(p)+s>d then d:=depth(p)+s; end end else begin x:=x+width(p); if type(p)>=rule_node then s:=0 @+else s:=shift_amount(p); if height(p)-s>h then h:=height(p)-s; if depth(p)+s>d then d:=depth(p)+s; end; end @z %------------------------- @x [33] m.654 @= begin f:=font(p); i:=char_info(f)(character(p)); hd:=height_depth(i); x:=x+char_width(f)(i);@/ s:=char_height(f)(hd);@+if s>h then h:=s; s:=char_depth(f)(hd);@+if s>d then d:=s; p:=link(p); end @y @= begin f:=font(p); i:=char_info(f)(character(p)); hd:=height_depth(i); if is_rotated(hpack_dir) then begin x:=x+char_height(f)(hd)+char_depth(f)(hd);@/ s:=char_width(f)(i) div 2;@+if s>h then h:=s; s:=char_width(f)(i) div 2;@+if s>d then d:=s; end else if dir_opposite(dir_tertiary[hpack_dir])(dir_tertiary[box_dir(r)]) then begin x:=x+char_width(f)(i);@/ s:=char_depth(f)(hd);@+if s>h then h:=s; s:=char_height(f)(hd);@+if s>d then d:=s; end else begin x:=x+char_width(f)(i);@/ s:=char_height(f)(hd);@+if s>h then h:=s; s:=char_depth(f)(hd);@+if s>d then d:=s; end; p:=link(p); end @z %------------------------- @x [33] m.666 @ @= if (-x-total_shrink[normal]>hfuzz)or(hbadness<100) then begin if (overfull_rule>0)and(-x-total_shrink[normal]>hfuzz) then begin while link(q)<>null do q:=link(q); link(q):=new_rule; width(link(q)):=overfull_rule; end; @y @ @= if (-x-total_shrink[normal]>hfuzz)or(hbadness<100) then begin if (overfull_rule>0)and(-x-total_shrink[normal]>hfuzz) then begin while link(q)<>null do q:=link(q); link(q):=new_rule; rule_dir(link(q)):=box_dir(r); width(link(q)):=overfull_rule; end; @z %------------------------- @x [33] m.668 @p function vpackage(@!p:pointer;@!h:scaled;@!m:small_number;@!l:scaled): pointer; label common_ending, exit; var r:pointer; {the box node that will be returned} @!w,@!d,@!x:scaled; {width, depth, and natural height} @!s:scaled; {shift amount} @!g:pointer; {points to a glue specification} @!o:glue_ord; {order of infinity} begin last_badness:=0; r:=get_node(box_node_size); type(r):=vlist_node; @y @p function vpackage(@!p:pointer;@!h:scaled;@!m:small_number;@!l:scaled): pointer; label common_ending, exit; var r:pointer; {the box node that will be returned} @!w,@!d,@!x:scaled; {width, depth, and natural height} @!s:scaled; {shift amount} @!g:pointer; {points to a glue specification} @!o:glue_ord; {order of infinity} begin last_badness:=0; r:=get_node(box_node_size); type(r):=vlist_node; if pack_direction=-1 then box_dir(r):=body_direction else begin box_dir(r):=pack_direction; pack_direction:=-1; end; @z %------------------------- @x [33] m.670 @ @= begin x:=x+d+height(p); d:=depth(p); if type(p)>=rule_node then s:=0 @+else s:=shift_amount(p); if width(p)+s>w then w:=width(p)+s; end @y @ @= begin if (type(p)=hlist_node) or (type(p)=vlist_node) then begin if dir_orthogonal(dir_primary[box_dir(p)])(dir_primary[box_dir(r)]) then begin x:=x+d+(width(p) div 2); d:=width(p) div 2; s:=shift_amount(p); if depth(p)+height(p)+s>w then w:=depth(p)+height(p)+s; end else if (type(p)=hlist_node) and (is_mirrored(box_dir(p))) then begin x:=x+d+depth(p); d:=height(p); s:=shift_amount(p); if width(p)+s>w then w:=width(p)+s; end else begin x:=x+d+height(p); d:=depth(p); s:=shift_amount(p); if width(p)+s>w then w:=width(p)+s; end end else begin x:=x+d+height(p); d:=depth(p); if type(p)>=rule_node then s:=0 @+else s:=shift_amount(p); if width(p)+s>w then w:=width(p)+s; end; end @z %------------------------- @x [33] m.679 begin d:=width(baseline_skip)-prev_depth-height(b); if d= @y @!internal_right_box_width:integer; {running \.{\\localrightbox} width} @!paragraph_dir:integer; {main direction of paragraph} @!line_break_dir:integer; {current direction within paragraph} @!break_c_htdp:quarterword; {height-depth entry in |char_info|} @!temp_no_whatsits:integer; {used when closing group} @!temp_no_dirs:integer; {used when closing group} @!temporary_dir:integer; @!dir_ptr,@!dir_tmp,@!dir_rover:pointer; @ @= temp_no_whatsits:=0; temp_no_dirs:=0; temporary_dir:=0; dir_ptr:=null; dir_tmp:=null; dir_rover:=null; @z %------------------------- @x [39] m.816 link(tail):=new_param_glue(par_fill_skip_code); @y final_par_glue:=new_param_glue(par_fill_skip_code); link(tail):=final_par_glue; @z %------------------------- @x [38] m.816 init_cur_lang:=prev_graf mod @'200000; init_l_hyf:=prev_graf div @'20000000; init_r_hyf:=(prev_graf div @'200000) mod @'100; @y init_cur_lang:=prev_graf mod @'200000; init_l_hyf:=prev_graf div @'20000000; init_r_hyf:=(prev_graf div @'200000) mod @'100; paragraph_dir:=local_par_dir(link(head)); line_break_dir:=paragraph_dir; @; @z %------------------------- @x [39] m.821 @!pass_number:halfword; {the number of passive nodes allocated on this pass} @y @!pass_number:halfword; {the number of passive nodes allocated on this pass} @!final_par_glue:pointer; @z %------------------------- @x [38] m.841 @= if is_char_node(v) then begin f:=font(v); break_width[1]:=break_width[1]-char_width(f)(char_info(f)(character(v))); end else case type(v) of ligature_node: begin f:=font(lig_char(v));@/ break_width[1]:=@|break_width[1]- char_width(f)(char_info(f)(character(lig_char(v)))); end; hlist_node,vlist_node,rule_node,kern_node: break_width[1]:=break_width[1]-width(v); @y @= if is_char_node(v) then begin f:=font(v); if is_rotated(line_break_dir) then begin break_c_htdp:=height_depth(char_info(f)(character(v))); break_width[1]:=break_width[1]-char_height(f)(break_c_htdp) -char_depth(f)(break_c_htdp); end else break_width[1]:=break_width[1]-char_width(f)(char_info(f)(character(v))); end else case type(v) of ligature_node: begin f:=font(lig_char(v));@/ if is_rotated(line_break_dir) then begin break_c_htdp:=height_depth(char_info(f)(character(lig_char(v)))); break_width[1]:=break_width[1]-char_height(f)(break_c_htdp) -char_depth(f)(break_c_htdp); end else break_width[1]:=@|break_width[1]- char_width(f)(char_info(f)(character(lig_char(v)))); end; hlist_node,vlist_node: if not (dir_orthogonal(dir_primary[box_dir(v)])(dir_primary[line_break_dir])) then break_width[1]:=break_width[1]-width(v) else break_width[1]:=break_width[1]-(depth(v)+height(v)); rule_node,kern_node: break_width[1]:=break_width[1]-width(v); @z %------------------------- @x [38] m.842 @ @= if is_char_node(s) then begin f:=font(s); break_width[1]:=@|break_width[1]+char_width(f)(char_info(f)(character(s))); end else case type(s) of ligature_node: begin f:=font(lig_char(s)); break_width[1]:=break_width[1]+ char_width(f)(char_info(f)(character(lig_char(s)))); end; hlist_node,vlist_node,rule_node,kern_node: break_width[1]:=break_width[1]+width(s); @y @ @= if is_char_node(s) then begin f:=font(s); if is_rotated(line_break_dir) then begin break_c_htdp:=height_depth(char_info(f)(character(s))); break_width[1]:=break_width[1]+char_height(f)(break_c_htdp) +char_depth(f)(break_c_htdp); end else break_width[1]:=@|break_width[1]+char_width(f)(char_info(f)(character(s))); end else case type(s) of ligature_node: begin f:=font(lig_char(s)); if is_rotated(line_break_dir) then begin break_c_htdp:=height_depth(char_info(f)(character(lig_char(s)))); break_width[1]:=break_width[1]+char_height(f)(break_c_htdp) +char_depth(f)(break_c_htdp); end else break_width[1]:=break_width[1]+ char_width(f)(char_info(f)(character(lig_char(s)))); end; hlist_node,vlist_node: if not (dir_orthogonal(dir_primary[box_dir(s)])(dir_primary[line_break_dir])) then break_width[1]:=break_width[1]+width(s) else break_width[1]:=break_width[1]+(depth(s)+height(s)); rule_node,kern_node: break_width[1]:=break_width[1]+width(s); @z %------------------------- @x [38] m.844 passive_right_box_width(q):=internal_right_box_width; @y passive_right_box_width(q):=internal_right_box_width; @z %------------------------- @x [38] m.866 hlist_node,vlist_node,rule_node: act_width:=act_width+width(cur_p); @y hlist_node,vlist_node: if not (dir_orthogonal(dir_primary[box_dir(cur_p)])(dir_primary[line_break_dir])) then act_width:=act_width+width(cur_p) else act_width:=act_width+(depth(cur_p)+height(cur_p)); rule_node: act_width:=act_width+width(cur_p); @z %------------------------- @x [38] m.866 act_width:=act_width+char_width(f)(char_info(f)(character(lig_char(cur_p)))); @y if is_rotated(line_break_dir) then begin break_c_htdp:=height_depth(char_info(f)(character(lig_char(cur_p)))); act_width:=act_width+char_height(f)(break_c_htdp) +char_depth(f)(break_c_htdp); end else act_width:=act_width+char_width(f)(char_info(f)(character(lig_char(cur_p)))); @z %------------------------- @x [38] m.867 act_width:=act_width+char_width(f)(char_info(f)(character(cur_p))); @y if is_rotated(line_break_dir) then begin break_c_htdp:=height_depth(char_info(f)(character(cur_p))); act_width:=act_width+char_height(f)(break_c_htdp) +char_depth(f)(break_c_htdp); end else act_width:=act_width+char_width(f)(char_info(f)(character(cur_p))); @z %------------------------- @x [38] m.870 @ @= if is_char_node(s) then begin f:=font(s); disc_width:=disc_width+char_width(f)(char_info(f)(character(s))); end else case type(s) of ligature_node: begin f:=font(lig_char(s)); disc_width:=disc_width+ char_width(f)(char_info(f)(character(lig_char(s)))); end; hlist_node,vlist_node,rule_node,kern_node: disc_width:=disc_width+width(s); @y @ @= if is_char_node(s) then begin f:=font(s); if is_rotated(line_break_dir) then begin break_c_htdp:=height_depth(char_info(f)(character(s))); disc_width:=disc_width+char_height(f)(break_c_htdp) +char_depth(f)(break_c_htdp); end else disc_width:=disc_width+char_width(f)(char_info(f)(character(s))); end else case type(s) of ligature_node: begin f:=font(lig_char(s)); if is_rotated(line_break_dir) then begin break_c_htdp:=height_depth(char_info(f)(character(lig_char(s)))); disc_width:=disc_width+char_height(f)(break_c_htdp) +char_depth(f)(break_c_htdp); end else disc_width:=disc_width+ char_width(f)(char_info(f)(character(lig_char(s)))); end; hlist_node,vlist_node: if not (dir_orthogonal(dir_primary[box_dir(s)])(dir_primary[line_break_dir])) then disc_width:=disc_width+width(s) else disc_width:=disc_width+(depth(s)+height(s)); rule_node,kern_node: disc_width:=disc_width+width(s); @z %------------------------- @x [38] m.871 @ @= if is_char_node(s) then begin f:=font(s); act_width:=act_width+char_width(f)(char_info(f)(character(s))); end else case type(s) of ligature_node: begin f:=font(lig_char(s)); act_width:=act_width+ char_width(f)(char_info(f)(character(lig_char(s)))); end; hlist_node,vlist_node,rule_node,kern_node: act_width:=act_width+width(s); @y @ @= if is_char_node(s) then begin f:=font(s); if is_rotated(line_break_dir) then begin break_c_htdp:=height_depth(char_info(f)(character(s))); act_width:=act_width+char_height(f)(break_c_htdp) +char_depth(f)(break_c_htdp); end else act_width:=act_width+char_width(f)(char_info(f)(character(s))); end else case type(s) of ligature_node: begin f:=font(lig_char(s)); if is_rotated(line_break_dir) then begin break_c_htdp:=height_depth(char_info(f)(character(lig_char(s)))); act_width:=act_width+char_height(f)(break_c_htdp) +char_depth(f)(break_c_htdp); end else act_width:=act_width+ char_width(f)(char_info(f)(character(lig_char(s)))); end; hlist_node,vlist_node: if not (dir_orthogonal(dir_primary[box_dir(s)])(dir_primary[line_break_dir])) then act_width:=act_width+width(s) else act_width:=act_width+(depth(s)+height(s)); rule_node,kern_node: act_width:=act_width+width(s); @z %------------------------- @x [39] m.877 @ The total number of lines that will be set by |post_line_break| is |best_line-prev_graf-1|. The last breakpoint is specified by |break_node(best_bet)|, and this passive node points to the other breakpoints via the |prev_break| links. The finishing-up phase starts by linking the relevant passive nodes in forward order, changing |prev_break| to |next_break|. (The |next_break| fields actually reside in the same memory space as the |prev_break| fields did, but we give them a new name because of their new significance.) Then the lines are justified, one by one. @d next_break==prev_break {new name for |prev_break| after links are reversed} @= procedure post_line_break(@!final_widow_penalty:integer); label done,done1; var q,@!r,@!s:pointer; {temporary registers for list manipulation} @!disc_break:boolean; {was the current break at a discretionary node?} @!post_disc_break:boolean; {and did it have a nonempty post-break part?} @!cur_width:scaled; {width of line number |cur_line|} @!cur_indent:scaled; {left margin of line number |cur_line|} @!t:quarterword; {used for replacement counts in discretionary nodes} @!pen:integer; {use when calculating penalties between lines} @!cur_line: halfword; {the current line number being justified} begin @; cur_line:=prev_graf+1; repeat @; incr(cur_line); cur_p:=next_break(cur_p); if cur_p<>null then if not post_disc_break then @; until cur_p=null; if (cur_line<>best_line)or(link(temp_head)<>null) then confusion("line breaking"); @:this can't happen line breaking}{\quad line breaking@> prev_graf:=best_line-1; end; @y @ The total number of lines that will be set by |post_line_break| is |best_line-prev_graf-1|. The last breakpoint is specified by |break_node(best_bet)|, and this passive node points to the other breakpoints via the |prev_break| links. The finishing-up phase starts by linking the relevant passive nodes in forward order, changing |prev_break| to |next_break|. (The |next_break| fields actually reside in the same memory space as the |prev_break| fields did, but we give them a new name because of their new significance.) Then the lines are justified, one by one. The |post_line_break| must also keep an dir stack, so that it can output end direction instructions at the ends of lines and begin direction instructions at the beginnings of lines. @d next_break==prev_break {new name for |prev_break| after links are reversed} @= procedure post_line_break(@!final_widow_penalty:integer); label done,done1; var q,@!r,@!s:pointer; {temporary registers for list manipulation} @!disc_break:boolean; {was the current break at a discretionary node?} @!post_disc_break:boolean; {and did it have a nonempty post-break part?} @!cur_width:scaled; {width of line number |cur_line|} @!cur_indent:scaled; {left margin of line number |cur_line|} @!t:quarterword; {used for replacement counts in discretionary nodes} @!pen:integer; {use when calculating penalties between lines} @!cur_line: halfword; {the current line number being justified} begin dir_ptr:=dir_save; @; cur_line:=prev_graf+1; repeat @; incr(cur_line); cur_p:=next_break(cur_p); if cur_p<>null then if not post_disc_break then @; until cur_p=null; if (cur_line<>best_line)or(link(temp_head)<>null) then confusion("line breaking"); @:this can't happen line breaking}{\quad line breaking@> prev_graf:=best_line-1; dir_save:=dir_ptr; end; @z %------------------------- @x [39] m.880 @= @; @; @y @= @; @; @; @; @z %------------------------- @x [39] m.881 if passive_right_box(cur_p)<>null then begin r:=temp_head; while link(r)<>q do r:=link(r); s:=copy_node_list(passive_right_box(cur_p)); link(r):=s; link(s):=q; end; delete_glue_ref(glue_ptr(q)); glue_ptr(q):=right_skip; subtype(q):=right_skip_code+1; add_glue_ref(right_skip); goto done; end else begin if type(q)=disc_node then @ else if (type(q)=math_node)or(type(q)=kern_node) then width(q):=0; end else begin q:=temp_head; while link(q)<>null do q:=link(q); end; @y if passive_right_box(cur_p)<>null then begin r:=temp_head; while link(r)<>q do r:=link(r); @; s:=copy_node_list(passive_right_box(cur_p)); link(r):=s; link(s):=q; end else begin r:=temp_head; while link(r)<>q do r:=link(r); @; end; delete_glue_ref(glue_ptr(q)); glue_ptr(q):=right_skip; subtype(q):=right_skip_code+1; add_glue_ref(right_skip); goto done; end else begin if type(q)=disc_node then @ else if (type(q)=math_node)or(type(q)=kern_node) then width(q):=0; end else begin q:=temp_head; while link(q)<>null do q:=link(q); end; r:=q; @; @z %------------------------- @x [39] m.888 append_to_vlist(just_box); if adjust_head<>adjust_tail then begin link(tail):=link(adjust_head); tail:=adjust_tail; end; adjust_tail:=null @y append_to_vlist(just_box); if adjust_head<>adjust_tail then begin link(tail):=link(adjust_head); tail:=adjust_tail; end; adjust_tail:=null @z %------------------------- @x [39] m.888 adjust_tail:=adjust_head; just_box:=hpack(q,cur_width,exactly); @y adjust_tail:=adjust_head; pack_direction:=paragraph_dir; just_box:=hpack(q,cur_width,exactly); @z %------------------------- @x [44] m.977 @p function vsplit(@!n:eight_bits; @!h:scaled):pointer; {extracts a page of height |h| from box |n|} label exit,done; var v:pointer; {the box to be split} p:pointer; {runs through the vlist} q:pointer; {points to where the break occurs} begin v:=box(n); if split_first_mark<>null then begin delete_token_ref(split_first_mark); split_first_mark:=null; delete_token_ref(split_bot_mark); split_bot_mark:=null; end; @; q:=vert_break(list_ptr(v),h,split_max_depth); @; q:=prune_page_top(q); p:=list_ptr(v); free_node(v,box_node_size); @y @p function vsplit(@!n:eight_bits; @!h:scaled):pointer; {extracts a page of height |h| from box |n|} label exit,done; var v:pointer; {the box to be split} vdir:integer; {the direction of the box to be split} p:pointer; {runs through the vlist} q:pointer; {points to where the break occurs} begin v:=box(n); vdir:=box_dir(v); if split_first_mark<>null then begin delete_token_ref(split_first_mark); split_first_mark:=null; delete_token_ref(split_bot_mark); split_bot_mark:=null; end; @; q:=vert_break(list_ptr(v),h,split_max_depth); @; q:=prune_page_top(q); p:=list_ptr(v); free_node(v,box_node_size); pack_direction:=vdir; @z %------------------------- @x [45] m.1001 if width(temp_ptr)>height(p) then width(temp_ptr):=width(temp_ptr)-height(p) else width(temp_ptr):=0; @y if (type(p)=hlist_node) and (is_mirrored(body_direction)) then begin if width(temp_ptr)>depth(p) then width(temp_ptr):=width(temp_ptr)-depth(p) else width(temp_ptr):=0; end else begin if width(temp_ptr)>height(p) then width(temp_ptr):=width(temp_ptr)-height(p) else width(temp_ptr):=0; end; @z %------------------------- @x [45] m.1002 begin page_total:=page_total+page_depth+height(p); page_depth:=depth(p); @y begin if (type(p)=hlist_node) and (is_mirrored(body_direction)) then begin page_total:=page_total+page_depth+depth(p); page_depth:=height(p); end else begin page_total:=page_total+page_depth+height(p); page_depth:=depth(p); end; @z %------------------------- @x [45] m.1017 set_equiv(box_base+255, vpackage(link(page_head),best_size,exactly,page_max_depth)); @y pack_direction:=body_direction; set_equiv(box_base+255, vpackage(link(page_head),best_size,exactly,page_max_depth)); @z %------------------------- @x [45] m.1021 temp_ptr:=list_ptr(box(n)); free_node(box(n),box_node_size); @y temp_ptr:=list_ptr(box(n)); free_node(box(n),box_node_size); pack_direction:=body_direction; @z %------------------------- @x [47] m.1063 non_math(left_brace): begin new_save_level(simple_group); eq_word_define(int_base+no_local_whatsits_code,0); end; any_mode(begin_group): begin new_save_level(semi_simple_group); eq_word_define(int_base+no_local_whatsits_code,0); end; any_mode(end_group): if cur_group=semi_simple_group then begin temp_no_whatsits:=no_local_whatsits; unsave; if temp_no_whatsits<>0 then if abs(mode)=hmode then @; end else off_save; @y non_math(left_brace): begin new_save_level(simple_group); eq_word_define(int_base+no_local_whatsits_code,0); eq_word_define(int_base+no_local_dirs_code,0); end; any_mode(begin_group): begin new_save_level(semi_simple_group); eq_word_define(int_base+no_local_whatsits_code,0); eq_word_define(int_base+no_local_dirs_code,0); end; any_mode(end_group): if cur_group=semi_simple_group then begin temp_no_whatsits:=no_local_whatsits; temp_no_dirs:=no_local_dirs; temporary_dir:=text_direction; if dir_level(text_dir_ptr)=cur_level then @; unsave; if abs(mode)=hmode then begin if temp_no_dirs<>0 then begin @; dir_dir(tail):=temporary_dir-64; end; if temp_no_whatsits<>0 then @; end end else off_save; @z %------------------------- @x [47] m.1068 simple_group: begin temp_no_whatsits:=no_local_whatsits; unsave; if temp_no_whatsits<>0 then if abs(mode)=hmode then @; end; @y simple_group: begin temp_no_whatsits:=no_local_whatsits; temp_no_dirs:=no_local_dirs; temporary_dir:=text_direction; if dir_level(text_dir_ptr)=cur_level then @; unsave; if abs(mode)=hmode then begin if temp_no_dirs<>0 then begin @; dir_dir(tail):=temporary_dir-64; end; if temp_no_whatsits<>0 then @; end end; @z %------------------------- @x [47] m.1083 begin k:=cur_chr-vtop_code; saved(0):=box_context; if k=hmode then if (box_context; end; pop_nest; box_end(saved(0)); end; @y procedure package(@!c:small_number); var h:scaled; {height of box} @!p:pointer; {first node in a box} @!d:scaled; {max depth} begin d:=box_max_depth; unsave; save_ptr:=save_ptr-5; pack_direction:=saved(3); if mode=-hmode then cur_box:=hpack(link(head),saved(2),saved(1)) else begin cur_box:=vpackage(link(head),saved(2),saved(1),d); if c=vtop_code then @; end; if saved(4)<>null then @; pop_nest; box_end(saved(0)); end; @z %------------------------- @x [47] m.1091 procedure new_graf(@!indented:boolean); begin prev_graf:=0; if (mode=vmode)or(head<>tail) then tail_append(new_param_glue(par_skip_code)); push_nest; mode:=hmode; space_factor:=1000; set_cur_lang; clang:=cur_lang; prev_graf:=(norm_min(left_hyphen_min)*@'100+norm_min(right_hyphen_min)) *@'200000+cur_lang; @; if indented then begin tail:=new_null_box; link(link(head)):=tail; width(tail):=par_indent;@+ end; @y procedure new_graf(@!indented:boolean); var p,q,dir_graf_tmp:pointer; begin prev_graf:=0; if (mode=vmode)or(head<>tail) then tail_append(new_param_glue(par_skip_code)); push_nest; mode:=hmode; space_factor:=1000; set_cur_lang; clang:=cur_lang; prev_graf:=(norm_min(left_hyphen_min)*@'100+norm_min(right_hyphen_min)) *@'200000+cur_lang; @; if indented then begin p:=new_null_box; box_dir(p):=par_direction; width(p):=par_indent;@+ tail_append(p); end; q:=tail; dir_rover:=text_dir_ptr; while dir_rover<>null do begin if (link(dir_rover)<>null) or (dir_dir(dir_rover)<>par_direction) then begin dir_graf_tmp:=new_dir(dir_dir(dir_rover)); link(dir_graf_tmp):=link(q); link(q):=dir_graf_tmp; end; dir_rover:=link(dir_rover); end; q:=head; while link(q)<>null do q:=link(q); tail:=q; @z %------------------------- @x [47] m.1096 procedure end_graf; begin if mode=hmode then begin if (head=tail) or (link(head)=tail) then pop_nest {null paragraphs are ignored, all contain a |local_paragraph| node} else line_break(widow_penalty); normal_paragraph; error_count:=0; end; end; @y procedure end_graf; begin if mode=hmode then begin if (head=tail) or (link(head)=tail) then pop_nest {null paragraphs are ignored, all contain a |local_paragraph| node} else line_break(widow_penalty); if dir_save<>null then begin flush_node_list(dir_save); dir_save:=null; end; normal_paragraph; error_count:=0; end; end; @z %------------------------- @x [48] m.1136 procedure push_math(@!c:group_code); begin push_nest; mode:=-mmode; incompleat_noad:=null; new_save_level(c); end; @y procedure push_math(@!c:group_code); begin if math_direction<>text_direction then dir_math_save:=true; push_nest; mode:=-mmode; incompleat_noad:=null; @; end; @z %------------------------- @x [48] m.1174 begin unsave; p:=fin_mlist(null); @y begin @; p:=fin_mlist(null); @z %------------------------- @x [48] m.1186 math_group: begin unsave; decr(save_ptr);@/ @y math_group: begin @; decr(save_ptr);@/ @z %------------------------- @x [48] m.1191 else begin p:=fin_mlist(p); unsave; {end of |math_left_group|} @y else begin p:=fin_mlist(p); @; {end of |math_left_group|} @z %------------------------- @x [48] m.1194 procedure after_math; var l:boolean; {`\.{\\leqno}' instead of `\.{\\eqno}'} @!danger:boolean; {not enough symbol fonts are present} @!m:integer; {|mmode| or |-mmode|} @!p:pointer; {the formula} @!a:pointer; {box containing equation number} @@; begin danger:=false; @; m:=mode; l:=false; p:=fin_mlist(null); {this pops the nest} if mode=-m then {end of equation number} begin @; cur_mlist:=p; cur_style:=text_style; mlist_penalties:=false; mlist_to_hlist; a:=hpack(link(temp_head),natural); unsave; decr(save_ptr); {now |cur_group=math_shift_group|} if saved(0)=1 then l:=true; @y procedure after_math; var l:boolean; {`\.{\\leqno}' instead of `\.{\\eqno}'} @!danger:boolean; {not enough symbol fonts are present} @!m:integer; {|mmode| or |-mmode|} @!p:pointer; {the formula} @!a:pointer; {box containing equation number} @@; begin danger:=false; @; m:=mode; l:=false; p:=fin_mlist(null); {this pops the nest} if mode=-m then {end of equation number} begin @; cur_mlist:=p; cur_style:=text_style; mlist_penalties:=false; mlist_to_hlist; a:=hpack(link(temp_head),natural); @; decr(save_ptr); {now |cur_group=math_shift_group|} if saved(0)=1 then l:=true; @z %------------------------- @x [48] m.1196 @= begin tail_append(new_math(math_surround,before)); cur_mlist:=p; cur_style:=text_style; mlist_penalties:=(mode>0); mlist_to_hlist; link(tail):=link(temp_head); while link(tail)<>null do tail:=link(tail); tail_append(new_math(math_surround,after)); space_factor:=1000; unsave; end @y @ = begin tail_append(new_math(math_surround,before)); if dir_math_save then @; cur_mlist:=p; cur_style:=text_style; mlist_penalties:=(mode>0); mlist_to_hlist; link(tail):=link(temp_head); while link(tail)<>null do tail:=link(tail); if dir_math_save then @; dir_math_save:=false; tail_append(new_math(math_surround,after)); space_factor:=1000; @; end @z %------------------------- @x [48] m.1200 procedure resume_after_display; begin if cur_group<>math_shift_group then confusion("display"); @:this can't happen display}{\quad display@> unsave; prev_graf:=prev_graf+3; @y procedure resume_after_display; begin if cur_group<>math_shift_group then confusion("display"); @:this can't happen display}{\quad display@> @; prev_graf:=prev_graf+3; @z %------------------------- @x [49] m.1210 any_mode(assign_int), @y any_mode(assign_int), any_mode(assign_dir), @z %------------------------- @x [49] m.1228 assign_dimen: begin p:=cur_chr; scan_optional_equals; scan_normal_dimen; word_define(p,cur_val); end; @y assign_dir: begin @ end; assign_dimen: begin p:=cur_chr; scan_optional_equals; scan_normal_dimen; word_define(p,cur_val); end; @z %------------------------- @x [49] m.1257 @!flushable_string:str_number; {string not yet referenced} @y @!natural_dir:integer;{the natural direction of the font} @!flushable_string:str_number; {string not yet referenced} @z %------------------------- @x [49] m.1257 if scan_keyword("offset") then begin scan_int; offset:=cur_val; if (cur_val<0) then begin print_err("Illegal offset has been changed to 0"); help1("The offset must be bigger than 0."); int_error(cur_val); offset:=0; end end else offset:=0; name_in_progress:=false; @; f:=read_font_info(u,cur_name,cur_area,s,offset); @y if scan_keyword("offset") then begin scan_int; offset:=cur_val; if (cur_val<0) then begin print_err("Illegal offset has been changed to 0"); help1("The offset must be bigger than 0."); int_error(cur_val); offset:=0; end end else offset:=0; if scan_keyword("naturaldir") then begin scan_dir; natural_dir:=cur_val; end else natural_dir:=-1; name_in_progress:=false; @; f:=read_font_info(u,cur_name,cur_area,s,offset,natural_dir); @z %------------------------- @x [51] m.1337 if (locescape) then start_input; {\.{\\input} assumed} @y if (locescape) then start_input; {\.{\\input} assumed} @; @z %------------------------- @x [53] m.1341 @d language_node=4 {|subtype| in whatsits that change the current language} @y @d language_node=4 {|subtype| in whatsits that change the current language} @d dir_node_size=4 {number of words in change direction node} @d dir_dir(#)==info(#+1) {keep the direction to be taken} @d dir_level(#)==link(#+1) {the save level at which the direction was defined} @d dir_dvi_ptr(#)==info(#+2) {for reflecting dvi output} @d dir_dvi_h(#)==info(#+3) {for reflecting dvi output} @z %------------------------- @x [53] m.1342 @!write_open:array[0..17] of boolean; @y @!write_open:array[0..17] of boolean; @!neg_wd:scaled; @!pos_wd:scaled; @!neg_ht:scaled; @!dvi_direction:integer; @!dir_primary:array[0..31] of 0..31; @!dir_secondary:array[0..31] of 0..31; @!dir_tertiary:array[0..31] of 0..31; @!dir_rearrange:array[0..3] of 0..31; @!dir_names:array[0..3] of str_number; @!text_dir_ptr:pointer; @!text_dir_tmp:pointer; @z %------------------------- @x [53] m.1343 for k:=0 to 17 do write_open[k]:=false; @y for k:=0 to 17 do write_open[k]:=false; set_new_eqtb_int(dir_base+page_direction_code,0); set_new_eqtb_int(dir_base+body_direction_code,0); set_new_eqtb_int(dir_base+par_direction_code,0); set_new_eqtb_int(dir_base+text_direction_code,0); set_new_eqtb_int(dir_base+math_direction_code,0); pack_direction:=-1; set_new_eqtb_sc(dimen_base+page_height_code,55380984); {29.7cm} set_new_eqtb_sc(dimen_base+page_width_code,39158276); {21cm} set_new_eqtb_sc(dimen_base+page_bottom_offset_code,page_height-9472573); {-2 inches} set_new_eqtb_sc(dimen_base+page_right_offset_code,page_width-9472573); {-2 inches} for k:= 0 to 7 do begin dir_primary [k ]:=dir_T; dir_primary [k+ 8]:=dir_L; dir_primary [k+16]:=dir_B; dir_primary [k+24]:=dir_R; end; for k:= 0 to 3 do begin dir_secondary[k ]:=dir_L; dir_secondary[k+ 4]:=dir_R; dir_secondary[k+ 8]:=dir_T; dir_secondary[k+12]:=dir_B; dir_secondary[k+16]:=dir_L; dir_secondary[k+20]:=dir_R; dir_secondary[k+24]:=dir_T; dir_secondary[k+28]:=dir_B; end; for k:=0 to 7 do begin dir_tertiary[k*4 ]:=dir_T; dir_tertiary[k*4+1]:=dir_L; dir_tertiary[k*4+2]:=dir_B; dir_tertiary[k*4+3]:=dir_R; end; dir_rearrange[0]:=0; dir_rearrange[1]:=0; dir_rearrange[2]:=1; dir_rearrange[3]:=1; dir_names[0]:="T"; dir_names[1]:="L"; dir_names[2]:="B"; dir_names[3]:="R"; @z %------------------------- @x [53] m.1344 @d local_par_node=6 {|subtype| in whatsits for local paragraph node} @y @d local_par_node=6 {|subtype| in whatsits for local paragraph node} @d dir_node=7 {|subtype| in whatsits for change direction node} @z %------------------------- @x [53] m.1344 primitive("localinterlinepenalty",assign_int,local_inter_line_penalty_code);@/ primitive("localbrokenpenalty",assign_int,local_broken_penalty_code);@/ @y primitive("localinterlinepenalty",assign_int,local_inter_line_penalty_code);@/ primitive("localbrokenpenalty",assign_int,local_broken_penalty_code);@/ primitive("pagedir",assign_dir,dir_base+page_direction_code);@/ primitive("bodydir",assign_dir,dir_base+body_direction_code);@/ primitive("pardir",assign_dir,dir_base+par_direction_code);@/ primitive("textdir",assign_dir,dir_base+text_direction_code);@/ primitive("mathdir",assign_dir,dir_base+math_direction_code);@/ primitive("pageheight",assign_dimen,dimen_base+page_height_code);@/ primitive("pagewidth",assign_dimen,dimen_base+page_width_code);@/ { |primitive("pagerightoffset",assign_dimen,dimen_base+page_right_offset_code);| |primitive("pagebottomoffset",assign_dimen,dimen_base+page_bottom_offset_code);| } @z %------------------------- @x [53] m.1346 set_language_code:print_esc("setlanguage"); othercases print("[unknown extension!]") endcases; @y set_language_code:print_esc("setlanguage"); othercases print("[unknown extension!]") endcases; @z %------------------------- @x [53] m.1348 set_language_code:@; @y set_language_code:@; @z %------------------------- @x [53] m.1356 language_node:begin print_esc("setlanguage"); print_int(what_lang(p)); print(" (hyphenmin "); print_int(what_lhm(p)); print_char(","); print_int(what_rhm(p)); print_char(")"); end; @y language_node:begin print_esc("setlanguage"); print_int(what_lang(p)); print(" (hyphenmin "); print_int(what_lhm(p)); print_char(","); print_int(what_rhm(p)); print_char(")"); end; dir_node: if dir_dir(p)<0 then begin print_esc("enddir"); print(" "); print_dir(dir_dir(p)+64); end else begin print_esc("begindir"); print(" "); print_dir(dir_dir(p)); end; @z %------------------------- @x [53] m.1357 close_node,language_node: begin r:=get_node(small_node_size); words:=small_node_size; end; @y close_node,language_node: begin r:=get_node(small_node_size); words:=small_node_size; end; dir_node: begin r:=get_node(dir_node_size); words:=dir_node_size; end; @z %------------------------- @x [53] m.1358 close_node,language_node: free_node(p,small_node_size); @y close_node,language_node: free_node(p,small_node_size); dir_node: free_node(p,dir_node_size); @z %------------------------- @x [53] m.1360 @ @=do_nothing @y @ @= begin if subtype(p)=dir_node then begin @; end; end @z %------------------------- @x [53] m.1362 @=@+ adv_past(cur_p) else @ @y @=@+ adv_past(cur_p) else @ else @ @z %------------------------- @x [53] m.1366 @ @= out_what(p) @y @ @= if subtype(p)<>dir_node then out_what(p) else @ @z %------------------------- @x @d local_par_size==7 @y @d local_par_dir(#)==mem[#+7].int @d local_par_size==8 @z %------------------------- @x make_local_par_node:=p; @y local_par_dir(p):=par_direction; make_local_par_node:=p; @z %------------------------- @x @ @= ((type(q)=whatsit_node) and (subtype(q)=local_par_node)) @y @ @= ((type(q)=whatsit_node) and (subtype(q)=local_par_node)) @ @= case cur_chr of dir_base+page_direction_code: begin if its_all_over then begin scan_dir; eq_word_define(dir_base+page_direction_code,cur_val); end; end; dir_base+body_direction_code: begin if its_all_over then begin scan_dir; eq_word_define(dir_base+body_direction_code,cur_val); end; end; dir_base+par_direction_code: begin scan_dir; eq_word_define(dir_base+par_direction_code,cur_val); end; dir_base+text_direction_code: begin scan_dir; if (no_local_dirs>0) and (abs(mode)=hmode) then begin @; dir_dir(tail):=dir_dir(tail)-64; end; if dir_level(text_dir_ptr)=cur_level then @; eq_word_define(dir_base+text_direction_code,cur_val); @; if abs(mode)=hmode then begin @; dir_level(tail):=cur_level; end; eq_word_define(int_base+no_local_dirs_code,no_local_dirs+1); eq_word_define(int_base+level_local_dir_code,cur_level); end; dir_base+math_direction_code: begin scan_dir; eq_word_define(dir_base+math_direction_code,cur_val); end; end; @ @d push_dir(#)== begin dir_tmp:=new_dir(#); link(dir_tmp):=dir_ptr; dir_ptr:=dir_tmp; dir_ptr:=dir_tmp; end @d push_dir_node(#)== begin dir_tmp:=get_node(dir_node_size); type(dir_tmp):=whatsit_node; subtype(dir_tmp):=dir_node; dir_dir(dir_tmp):=dir_dir(#); dir_level(dir_tmp):=dir_level(#); dir_dvi_h(dir_tmp):=dir_dvi_h(#); dir_dvi_ptr(dir_tmp):=dir_dvi_ptr(#); link(dir_tmp):=dir_ptr; dir_ptr:=dir_tmp; end @d pop_dir_node== begin dir_tmp:=dir_ptr; dir_ptr:=link(dir_tmp); free_node(dir_tmp,dir_node_size); end @ @= function new_dir(s:small_number): pointer; var p:pointer; {the new node} begin p:=get_node(dir_node_size); type(p):=whatsit_node; subtype(p):=dir_node; dir_dir(p):=s; dir_dvi_h(p):=0; dir_dvi_ptr(p):=-1; dir_level(p):=cur_level; new_dir:=p; end @ @= tail_append(new_dir(math_direction)) @ @= tail_append(new_dir(math_direction-64)) @ @= tail_append(new_dir(text_direction)) @ @= if subtype(cur_p)=dir_node then begin if dir_dir(cur_p)>=0 then begin line_break_dir:=dir_dir(cur_p); push_dir_node(cur_p); end else begin pop_dir_node; line_break_dir:=dir_dir(dir_ptr); end end @ @= begin if dir_dir(p)>=0 then begin hpack_dir:=dir_dir(p); push_dir_node(p); end else begin pop_dir_node; hpack_dir:=dir_dir(dir_ptr); end end @ @= begin dir_rover:=dir_ptr; while dir_rover<>null do begin dir_tmp:=new_dir(dir_dir(dir_rover)); link(dir_tmp):=link(temp_head); link(temp_head):=dir_tmp; dir_rover:=link(dir_rover); end end @ @= begin flush_node_list(dir_ptr); dir_ptr:=null; q:=link(temp_head); while q<>cur_break(cur_p) do begin if not is_char_node(q) then if type(q)=whatsit_node then if subtype(q)=dir_node then begin if dir_dir(q)>=0 then begin push_dir_node(q) end else if dir_ptr<>null then if dir_dir(dir_ptr)=(dir_dir(q)+64) then begin pop_dir_node; end; end; q:=link(q); end end @ @= if dir_ptr<>null then begin if link(r)=q then begin dir_rover:=dir_ptr; while dir_rover<>null do begin dir_tmp:=new_dir(dir_dir(dir_rover)-64); link(dir_tmp):=q; link(r):=dir_tmp; r:=dir_tmp; dir_rover:=link(dir_rover); end; end else if r=final_par_glue then begin s:=temp_head; while link(s)<>r do s:=link(s); dir_rover:=dir_ptr; while dir_rover<>null do begin dir_tmp:=new_dir(dir_dir(dir_rover)-64); link(dir_tmp):=q; link(s):=dir_tmp; s:=dir_tmp; dir_rover:=link(dir_rover); end; end else begin dir_rover:=dir_ptr; s:=link(q); while dir_rover<>null do begin dir_tmp:=new_dir(dir_dir(dir_rover)-64); link(dir_tmp):=s; link(q):=dir_tmp; q:=dir_tmp; dir_rover:=link(dir_rover); end; r:=q; end end @ @= begin while dir_ptr<>null do pop_dir_node end @ @= begin unsave; decr(save_ptr); flush_node_list(text_dir_ptr); text_dir_ptr:=saved(0); end @ @= begin saved(0):=text_dir_ptr; text_dir_ptr:=new_dir(math_direction); incr(save_ptr); new_save_level(c); eq_word_define(dir_base+body_direction_code,math_direction); eq_word_define(dir_base+par_direction_code,math_direction); eq_word_define(dir_base+text_direction_code,math_direction); eq_word_define(int_base+level_local_dir_code,cur_level); end @ @= begin if spec_direction<>-1 then begin saved(3):=text_dir_ptr; text_dir_ptr:=new_dir(spec_direction); end else saved(3):=null; end @ @= begin flush_node_list(text_dir_ptr); text_dir_ptr:=saved(4); end @ @= begin text_dir_tmp:=new_dir(text_direction); link(text_dir_tmp):=text_dir_ptr; text_dir_ptr:=text_dir_tmp; end @ @= begin text_dir_tmp:=link(text_dir_ptr); free_node(text_dir_ptr,dir_node_size); text_dir_ptr:=text_dir_tmp; end @ @= begin text_dir_ptr:=new_dir(0); end @ @= begin dir_ptr:=null; push_dir(dvi_direction); dir_dvi_ptr(dir_ptr):=dvi_ptr; end @ @= begin dir_ptr:=null; push_dir(hpack_dir) end @ @= begin dir_ptr:=null; push_dir(paragraph_dir); end @ @= begin if dir_dir(p)>=0 then begin synch_h; synch_v; push_dir_node(p); if dir_opposite(dir_secondary[dir_dir(dir_ptr)])(dir_secondary[dvi_direction]) then begin if (dir_secondary[dvi_direction]=0) or (dir_secondary[dvi_direction]=2) then dvi_out(down4) else dvi_out(right4); dir_dvi_ptr(dir_ptr):=dvi_ptr; dir_dvi_h(dir_ptr):=dvi_h; dvi_four(0); cur_h:=0; dvi_h:=0; end else begin dir_dvi_ptr(dir_ptr):=dvi_ptr; dir_dvi_h(dir_ptr):=dvi_h; end; dvi_direction:=dir_dir(dir_ptr); end else begin dvi_dir_h:=dir_dvi_h(dir_ptr); dvi_dir_ptr:=dir_dvi_ptr(dir_ptr); pop_dir_node; synch_h; synch_v; dvi_direction:=dir_dir(dir_ptr); if dir_opposite(dir_secondary[dir_dir(p)+64])(dir_secondary[dvi_direction]) then begin dvi_temp_ptr:=dvi_ptr; dvi_ptr:=dvi_dir_ptr; if (dir_secondary[dvi_direction]=0) or (dir_secondary[dvi_direction]=1) then dvi_four(dvi_h) else dvi_four(-dvi_h); dvi_ptr:=dvi_temp_ptr; if (dir_secondary[dvi_direction]=0) or (dir_secondary[dvi_direction]=2) then dvi_out(down4) else dvi_out(right4); if (dir_secondary[dvi_direction]=0) or (dir_secondary[dvi_direction]=1) then dvi_four(dvi_h) else dvi_four(-dvi_h); end; cur_h:=dvi_dir_h+dvi_h; dvi_h:=cur_h; end end @z