diff options
Diffstat (limited to 'Build/source/texk/web2c/pdftexdir/hz.ch')
-rw-r--r-- | Build/source/texk/web2c/pdftexdir/hz.ch | 1935 |
1 files changed, 0 insertions, 1935 deletions
diff --git a/Build/source/texk/web2c/pdftexdir/hz.ch b/Build/source/texk/web2c/pdftexdir/hz.ch deleted file mode 100644 index d8ec58fb5e7..00000000000 --- a/Build/source/texk/web2c/pdftexdir/hz.ch +++ /dev/null @@ -1,1935 +0,0 @@ -% WEB change file containing HZ extensions for pdfTeX -% -% Copyright (c) 1996-2002 Han Th\^e\llap{\raise 0.5ex\hbox{\'{}}} Th\`anh, <thanh@pdftex.org> -% -% This file is part of pdfTeX. -% -% pdfTeX is free software; you can redistribute it and/or modify -% it under the terms of the GNU General Public License as published by -% the Free Software Foundation; either version 2 of the License, or -% (at your option) any later version. -% -% pdfTeX 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 General Public License for more details. -% -% You should have received a copy of the GNU General Public License -% along with pdfTeX; if not, write to the Free Software -% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -% -% $Id: //depot/Build/source.development/TeX/texk/web2c/pdftexdir/hz.ch#15 $ - -@x [155] - margin kerning -@d acc_kern=2 {|subtype| of kern nodes from accents} -@y -@d acc_kern=2 {|subtype| of kern nodes from accents} - -@# {memory structure for marginal kerns} -@d margin_kern_node = 40 -@d margin_kern_node_size = 3 -@d margin_char(#) == info(# + 2) - -@# {|subtype| of marginal kerns} -@d left_side == 0 -@d right_side == 1 - -@# {base for lp/rp/ef codes starts from 2: - 0 for |hyphen_char|, - 1 for |skew_char|} -@d lp_code_base == 2 -@d rp_code_base == 3 -@d ef_code_base == 4 - -@d max_hlist_stack = 512 {maximum fill level for |hlist_stack|} -{maybe good if larger than |2 * max_quarterword|, so that box nesting level would overflow first} -@z - -@x [183] - margin kerning - kern_node: @<Display kern |p|@>; -@y - margin_kern_node: begin - print_esc("kern"); - print_scaled(width(p)); - if subtype(p) = left_side then - print(" (left margin)") - else - print(" (right margin)"); - end; - kern_node: @<Display kern |p|@>; -@z - -@x [202] - margin kerning - kern_node,math_node,penalty_node: do_nothing; -@y - kern_node,math_node,penalty_node: do_nothing; - margin_kern_node: begin - free_avail(margin_char(p)); - free_node(p, margin_kern_node_size); - goto done; - end; -@z - -@x [206] - margin kerning -kern_node,math_node,penalty_node: begin r:=get_node(small_node_size); - words:=small_node_size; - end; -@y -kern_node,math_node,penalty_node: begin r:=get_node(small_node_size); - words:=small_node_size; - end; -margin_kern_node: begin - r := get_node(margin_kern_node_size); - fast_get_avail(margin_char(r)); - font(margin_char(r)) := font(margin_char(p)); - character(margin_char(r)) := character(margin_char(p)); - words := small_node_size; - end; -@z - -@x [236] -@d pdf_int_pars=pdftex_first_integer_code + 17 {total number of \pdfTeX's integer parameters} -@y -@d pdf_adjust_spacing_code = pdftex_first_integer_code + 17 {level of spacing adjusting} -@d pdf_protrude_chars_code = pdftex_first_integer_code + 18 {protrude chars at left/right edge of paragraphs} -@d pdf_tracing_fonts_code = pdftex_first_integer_code + 19 {level of font detail in log} -@d pdf_int_pars=pdftex_first_integer_code + 20 {total number of \pdfTeX's integer parameters} -@z - -@x [236] -@d error_context_lines==int_par(error_context_lines_code) -@y -@d error_context_lines==int_par(error_context_lines_code) -@# -@d pdf_adjust_spacing == int_par(pdf_adjust_spacing_code) -@d pdf_protrude_chars == int_par(pdf_protrude_chars_code) -@d pdf_tracing_fonts == int_par(pdf_tracing_fonts_code) -@z - -@x [237] -error_context_lines_code:print_esc("errorcontextlines"); -@y -error_context_lines_code:print_esc("errorcontextlines"); -@# -pdf_adjust_spacing_code: print_esc("pdfadjustspacing"); -pdf_protrude_chars_code: print_esc("pdfprotrudechars"); -pdf_tracing_fonts_code: print_esc("pdftracingfonts"); -@z - -@x [238] -primitive("errorcontextlines",assign_int,int_base+error_context_lines_code);@/ -@!@:error_context_lines_}{\.{\\errorcontextlines} primitive@> -@y -primitive("errorcontextlines",assign_int,int_base+error_context_lines_code);@/ -@!@:error_context_lines_}{\.{\\errorcontextlines} primitive@> -primitive("pdfadjustspacing",assign_int,int_base+pdf_adjust_spacing_code);@/ -@!@:pdf_adjust_spacing_}{\.{\\pdfadjustspacing} primitive@> -primitive("pdfprotrudechars",assign_int,int_base+pdf_protrude_chars_code);@/ -@!@:pdf_protrude_chars_}{\.{\\pdfprotrudechars} primitive@> -primitive("pdftracingfonts",assign_int,int_base+pdf_tracing_fonts_code);@/ -@!@:pdf_tracing_fonts_}{\.{\\pdftracingfonts} primitive@> -@z - -@x [267] - displaying fonts -@<Print the font identifier for |font(p)|@>= -print_esc(font_id_text(font(p))) -@y -@<Print the font identifier for |font(p)|@>= -begin - print_esc(font_id_text(font(p))); - if pdf_tracing_fonts > 0 then begin - print(" ("); - print(font_name[font(p)]); - if font_size[font(p)] <> font_dsize[font(p)] then begin - print("@@"); - print_scaled(font_size[font(p)]); - print("pt"); - end; - print(")"); - end else - if pdf_font_expand_ratio[font(p)] <> 0 then begin - print(" ("); - if pdf_font_expand_ratio[font(p)] > 0 then - print("+"); - print_int(pdf_font_expand_ratio[font(p)]); - print(")"); - end; -end -@z - -@x [413] - font expansion -var m:halfword; {|chr_code| part of the operand token} -@y -var m:halfword; {|chr_code| part of the operand token} - n, k: integer; {accumulators} -@z - -@x [426] - font expansion, margin kerning -begin scan_font_ident; -if m=0 then scanned_result(hyphen_char[cur_val])(int_val) -else scanned_result(skew_char[cur_val])(int_val); -@y -begin scan_font_ident; -if m=0 then scanned_result(hyphen_char[cur_val])(int_val) -else if m=1 then scanned_result(skew_char[cur_val])(int_val) -else begin - n := cur_val; - scan_char_num; - k := cur_val; - case m of - lp_code_base: scanned_result(get_lp_code(n, k))(int_val); - rp_code_base: scanned_result(get_rp_code(n, k))(int_val); - ef_code_base: scanned_result(get_ef_code(n, k))(int_val); - end; -end; -@z - -@x [468] -@d pdftex_convert_codes = pdftex_first_expand_code + 9 {end of \pdfTeX's command codes} -@y -@d left_margin_kern_code = pdftex_first_expand_code + 9 {command code for \.{\\leftmarginkern}} -@d right_margin_kern_code = pdftex_first_expand_code + 10 {command code for \.{\\rightmarginkern}} -@d pdftex_convert_codes = pdftex_first_expand_code + 11 {end of \pdfTeX's command codes} -@z - -@x [468] -primitive("pdfpageref",convert,pdf_page_ref_code);@/ -@!@:pdf_page_ref_}{\.{\\pdfpageref} primitive@> -@y -primitive("pdfpageref",convert,pdf_page_ref_code);@/ -@!@:pdf_page_ref_}{\.{\\pdfpageref} primitive@> -primitive("leftmarginkern",convert,left_margin_kern_code);@/ -@!@:left_margin_kern_}{\.{\\leftmarginkern} primitive@> -primitive("rightmarginkern",convert,right_margin_kern_code);@/ -@!@:right_margin_kern_}{\.{\\rightmarginkern} primitive@> -@z - -@x [469] - pdf_page_ref_code: print_esc("pdfpageref"); -@y - pdf_page_ref_code: print_esc("pdfpageref"); - left_margin_kern_code: print_esc("leftmarginkern"); - right_margin_kern_code: print_esc("rightmarginkern"); -@z - -@x [470] -var old_setting:0..max_selector; {holds |selector| setting} -@y -var old_setting:0..max_selector; {holds |selector| setting} -p, q: pointer; -@z - -@x [471] -pdf_page_ref_code: begin - scan_int; - if cur_val <= 0 then - pdf_error("pageref", "invalid page number"); -end; -@y -pdf_page_ref_code: begin - scan_int; - if cur_val <= 0 then - pdf_error("pageref", "invalid page number"); -end; -left_margin_kern_code, right_margin_kern_code: begin - scan_int; - if (box(cur_val) = null) or (type(box(cur_val)) <> hlist_node) then - pdf_error("marginkern", "a non-empty hbox expected") -end; -@z - -@x [472] -pdf_page_ref_code: print_int(get_obj(obj_type_page, cur_val, false)); -@y -pdf_page_ref_code: print_int(get_obj(obj_type_page, cur_val, false)); -left_margin_kern_code: begin - p := list_ptr(box(cur_val)); - if (p <> null) and (not is_char_node(p)) and - (type(p) = glue_node) and (subtype(p) = left_skip_code + 1) then - p := link(p); - if (p <> null) and (not is_char_node(p)) and - (type(p) = margin_kern_node) and (subtype(p) = left_side) then - print_scaled(width(p)) - else - print("0"); - print("pt"); -end; -right_margin_kern_code: begin - q := list_ptr(box(cur_val)); - p := null; - if q <> null then begin - p := prev_rightmost(q, null); - if (p <> null) and (not is_char_node(p)) and - (type(p) = glue_node) and (subtype(p) = right_skip_code + 1) then - p := prev_rightmost(q, p); - end; - if (p <> null) and (not is_char_node(p)) and - (type(p) = margin_kern_node) and (subtype(p) = right_side) then - print_scaled(width(p)) - else - print("0"); - print("pt"); -end; -@z - -@x [622] - margin kerning -glue_node: @<Move right or output leaders@>; -@y -glue_node: @<Move right or output leaders@>; -margin_kern_node, -@z - - -@x [???] - font expansion -@!tmp_f: internal_font_number; {for use with |pdf_init_font|} - -@y -@!tmp_f: internal_font_number; {for use with |pdf_init_font|} -@ Here come some subroutines to deal with expanded fonts for HZ-algorithm. - -@p -function init_font_base(v: integer): integer; -var i, j: integer; -begin - i := pdf_get_mem(256); - for j := 0 to 255 do - pdf_mem[i + j] := v; - init_font_base := i; -end; - -procedure set_lp_code(f: internal_font_number; c: eight_bits; i: integer); -begin - if pdf_font_lp_base[f] = 0 then - pdf_font_lp_base[f] := init_font_base(0); - pdf_mem[pdf_font_lp_base[f] + c] := fix_int(i, -1000, 1000); -end; - -procedure set_rp_code(f: internal_font_number; c: eight_bits; i: integer); -begin - if pdf_font_rp_base[f] = 0 then - pdf_font_rp_base[f] := init_font_base(0); - pdf_mem[pdf_font_rp_base[f] + c] := fix_int(i, -1000, 1000); -end; - -procedure set_ef_code(f: internal_font_number; c: eight_bits; i: integer); -begin - if pdf_font_ef_base[f] = 0 then - pdf_font_ef_base[f] := init_font_base(1000); - pdf_mem[pdf_font_ef_base[f] + c] := fix_int(i, 0, 1000); -end; - -function expand_font_name(f: internal_font_number; e: integer): str_number; -var old_setting:0..max_selector; {holds |selector| setting} -begin - old_setting:=selector; selector:=new_string; - print(font_name[f]); - if e > 0 then - print("+"); {minus sign will be printed by |print_int|} - print_int(e); - selector:=old_setting; - expand_font_name := make_string; -end; - -function auto_expand_font(f: internal_font_number; e: integer): internal_font_number; -{creates an expanded font from the base font; doesn't load expanded tfm at all} -var k: internal_font_number; - nw, nk, ni, i, j: integer; -begin - k := font_ptr + 1; - incr(font_ptr); - if (font_ptr >= font_max) then - overflow("maximum internal font number (font_max)", font_max); - font_name[k] := expand_font_name(f, e); - font_area[k] := font_area[f]; - font_id_text(k) := font_id_text(f); - hyphen_char[k] := hyphen_char[f]; - skew_char[k] := skew_char[f]; - font_bchar[k] := font_bchar[f]; - font_false_bchar[k] := font_false_bchar[f]; - font_bc[k] := font_bc[f]; - font_ec[k] := font_ec[f]; - font_size[k] := font_size[f]; - font_dsize[k] := font_dsize[f]; - font_params[k] := font_params[f]; - font_glue[k] := font_glue[f]; - bchar_label[k] := bchar_label[f]; - - char_base[k] := char_base[f]; - height_base[k] := height_base[f]; - depth_base[k] := depth_base[f]; - lig_kern_base[k] := lig_kern_base[f]; - exten_base[k] := exten_base[f]; - param_base[k] := param_base[f]; - - nw := height_base[f] - width_base[f]; - ni := lig_kern_base[f] - italic_base[f]; - nk := exten_base[f] - (kern_base[f] + kern_base_offset); - if (fmem_ptr + nw + ni + nk >= font_mem_size) then - overflow("number of words of font memory (font_mem_size)", font_mem_size); - width_base[k] := fmem_ptr; - italic_base[k] := width_base[k] + nw; - kern_base[k] := italic_base[k] + ni - kern_base_offset; - fmem_ptr := fmem_ptr + nw + ni + nk; - - for i := 0 to nw - 1 do - font_info[width_base[k] + i].sc := - round_xn_over_d(font_info[width_base[f] + i].sc, 1000 + e, 1000); - for i := 0 to ni - 1 do - font_info[italic_base[k] + i].sc := - round_xn_over_d(font_info[italic_base[f] + i].sc, 1000 + e, 1000); - for i := 0 to nk - 1 do - font_info[kern_base[k] + kern_base_offset + i].sc := - round_xn_over_d(font_info[kern_base[f] + kern_base_offset + i].sc, 1000 + e, 1000); - - auto_expand_font := k; -end; - -procedure set_expand_param(k, f: internal_font_number; e: integer); -var i, j: integer; -begin - if pdf_font_rp_base[f] = 0 then - pdf_font_rp_base[f] := init_font_base(0); - if pdf_font_lp_base[f] = 0 then - pdf_font_lp_base[f] := init_font_base(0); - if pdf_font_ef_base[f] = 0 then - pdf_font_ef_base[f] := init_font_base(1000); - pdf_font_expand_ratio[k] := e; - pdf_font_step[k] := pdf_font_step[f]; - pdf_font_auto_expand[k] := pdf_font_auto_expand[f]; - pdf_font_blink[k] := f; {???} - pdf_font_lp_base[k] := pdf_font_lp_base[f]; - pdf_font_rp_base[k] := pdf_font_rp_base[f]; - pdf_font_ef_base[k] := pdf_font_ef_base[f]; -end; - -function tfm_lookup(s: str_number; fs: scaled): internal_font_number; -{looks up for a TFM with name |s| loaded at |fs| size; if found then flushes |s|} -var k: internal_font_number; -begin - if fs <> 0 then begin - for k := font_base + 1 to font_ptr do - if str_eq_str(font_name[k], s) and (font_size[k] = fs) then begin - flush_str(s); - tfm_lookup := k; - return; - end; - end - else begin - for k := font_base + 1 to font_ptr do - if str_eq_str(font_name[k], s) then begin - flush_str(s); - tfm_lookup := k; - return; - end; - end; - tfm_lookup := null_font; -end; - -function load_expand_font(f: internal_font_number; e: integer): internal_font_number; -{loads font |f| expanded by |e| thousandths into font memory; |e| is nonzero -and is a multiple of |pdf_font_step[f]|} -label found; -var s: str_number; {font name} - k: internal_font_number; -begin - s := expand_font_name(f, e); - k := tfm_lookup(s, font_size[f]); - if k = null_font then begin - if pdf_font_auto_expand[f] then - k := auto_expand_font(f, e) - else - k := read_font_info(null_cs, s, "", font_size[f]); - end; - set_expand_param(k, f, e); - load_expand_font := k; -end; - -function auto_expand_vf(f: internal_font_number): boolean; -{check for a virtual auto-expanded font} -var save_f, bf, lf, k: internal_font_number; - e: integer; -begin - auto_expand_vf := false; - if (not pdf_font_auto_expand[f]) or (pdf_font_blink[f] = null_font) then - return; {not an auto-expanded font} - bf := pdf_font_blink[f]; - if pdf_font_type[bf] = new_font_type then {we must process the base font first} - begin - save_f := tmp_f; - tmp_f := bf; - do_vf; - tmp_f := save_f; - end; - - if pdf_font_type[bf] <> virtual_font_type then - return; {not a virtual font} - - e := pdf_font_expand_ratio[f]; - for k := 0 to vf_local_font_num[bf] - 1 do begin - lf := vf_default_font[bf] + k; - vf_e_fnts[vf_nf] := vf_e_fnts[lf]; - vf_i_fnts[vf_nf] := auto_expand_font(vf_i_fnts[lf], e); - set_expand_param(vf_i_fnts[vf_nf], vf_i_fnts[lf], e); - incr(vf_nf); - end; - vf_packet_base[f] := vf_packet_base[bf]; - vf_local_font_num[f] := vf_local_font_num[bf]; - vf_default_font[f] := vf_nf - vf_local_font_num[f]; - - pdf_font_type[f] := virtual_font_type; - auto_expand_vf := true; -end; - -function fix_expand_value(f: internal_font_number; e: integer): integer; -{return the multiple of |pdf_font_step[f]| that is nearest to |e|} -var step: integer; - max_expand: integer; - neg: boolean; -begin - fix_expand_value := 0; - if e = 0 then - return; - if e < 0 then begin - e := -e; - neg := true; - max_expand := -pdf_font_expand_ratio[pdf_font_shrink[f]]; - end - else begin - neg := false; - max_expand := pdf_font_expand_ratio[pdf_font_stretch[f]]; - end; - if e > max_expand then - e := max_expand - else begin - step := pdf_font_step[f]; - if e mod step > 0 then - e := step*round_xn_over_d(e, 1, step); - end; - if neg then - e := -e; - fix_expand_value := e; -end; - -function get_expand_font(f: internal_font_number; e: integer): internal_font_number; -{look up and create if not found an expanded version of |f|; |f| is an -expandable font; |e| is nonzero and is a multiple of |pdf_font_step[f]|} -var k: internal_font_number; -begin - k := pdf_font_elink[f]; - while k <> null_font do begin - if pdf_font_expand_ratio[k] = e then begin - get_expand_font := k; - return; - end; - k := pdf_font_elink[k]; - end; - k := load_expand_font(f, e); - pdf_font_elink[k] := pdf_font_elink[f]; - pdf_font_elink[f] := k; - get_expand_font := k; -end; - -function expand_font(f: internal_font_number; e: integer): internal_font_number; -{looks up for font |f| expanded by |e| thousandths, |e| is an arbitrary value -between max stretch and max shrink of |f|; if not found then creates it} -var max_expand: integer; -begin - expand_font := f; - if e = 0 then - return; - e := fix_expand_value(f, e); - if e = 0 then - return; - if pdf_font_elink[f] = null_font then - pdf_error("font expansion", "uninitialized pdf_font_elink"); - expand_font := get_expand_font(f, e); -end; - -procedure read_expand_font; {read font expansion spec and load expanded font} -var font_shrink, font_stretch, font_step: integer; - f: internal_font_number; - auto_expand: boolean; -begin - {read font expansion parameters} - scan_font_ident; - f := cur_val; - if f = null_font then - pdf_error("font expansion", "invalid font identifier"); - scan_optional_equals; - scan_int; - font_stretch := fix_int(cur_val, 0, 1000); - scan_int; - font_shrink := fix_int(cur_val, 0, 1000); - scan_int; - font_step := fix_int(cur_val, 0, 1000); - if font_step = 0 then - pdf_error("font expansion", "invalid step"); - font_stretch := font_stretch - font_stretch mod font_step; - if font_stretch < 0 then - font_stretch := 0; - font_shrink := font_shrink - font_shrink mod font_step; - if font_shrink < 0 then - font_shrink := 0; - if font_shrink = 1000 then - font_shrink := font_shrink - font_step; {don't allow zero-width font} - if (font_stretch = 0) and (font_shrink = 0) then - pdf_error("font expansion", "invalid limit"); - auto_expand := false; - if scan_keyword("autoexpand") then begin - auto_expand := true; - @<Scan an optional space@>; end; - - {check if the font can be expanded} - if (pdf_font_expand_ratio[f] <> 0) then - pdf_error("font expansion", "this font has been expanded by another font so it cannot be used now"); - if (pdf_font_step[f] <> 0) then - {this font has been expanded, ensure the expansion parameters are identical} - begin - if (pdf_font_step[f] <> font_step) or - ((pdf_font_stretch[f] = null_font) and (font_stretch <> 0)) or - ((pdf_font_stretch[f] <> null_font) and - (pdf_font_expand_ratio[pdf_font_stretch[f]] <> font_stretch)) or - ((pdf_font_shrink[f] = null_font) and (font_shrink <> 0)) or - ((pdf_font_shrink[f] <> null_font) and - (pdf_font_expand_ratio[pdf_font_shrink[f]] <> -font_shrink)) or - (pdf_font_auto_expand[f] <> auto_expand) - then - pdf_error("font expansion", "font has been expanded with different parameters"); - end - else begin - pdf_font_step[f] := font_step; - pdf_font_auto_expand[f] := auto_expand; - if font_stretch > 0 then - pdf_font_stretch[f] := get_expand_font(f, font_stretch); - if font_shrink > 0 then - pdf_font_shrink[f] := get_expand_font(f, -font_shrink); - end; -end; -@z - -@x [32f] - margin kerning -glue_node: @<(\pdfTeX) Move right or output leaders@>; -@y -glue_node: @<(\pdfTeX) Move right or output leaders@>; -margin_kern_node, -@z - -@x [649] - font expansion -@ Here now is |hpack|, which contains few if any surprises. - -@p function hpack(@!p:pointer;@!w:scaled;@!m:small_number):pointer; -@y -@ @<Glob...@>= -@!pdf_font_blink: ^internal_font_number; {link to base font (used for expanded fonts only)} -@!pdf_font_elink: ^internal_font_number; {link to expanded fonts (used for base fonts only)} -@!pdf_font_stretch: ^integer; {limit of stretching} -@!pdf_font_shrink: ^integer; {limit of shrinking} -@!pdf_font_step: ^integer; {amount of one step of expansion} -@!pdf_font_expand_ratio: ^integer; {expansion ratio of a particular font} -@!pdf_font_auto_expand: ^boolean; {this font is auto-expanded?} -@!pdf_font_lp_base: ^integer; {base of left-protruding factor} -@!pdf_font_rp_base: ^integer; {base of right-protruding factor} -@!pdf_font_ef_base: ^integer; {base of font expansion factor} -@!font_expand_ratio: integer; {current expansion ratio} -@!last_leftmost_char: pointer; -@!last_rightmost_char: pointer; -@!hlist_stack:array[0..max_hlist_stack] of pointer; {stack for |find_protchar_left()| and |find_protchar_right()|} -@!hlist_stack_level:0..max_hlist_stack; {fill level for |hlist_stack|} - -@ @d cal_margin_kern_var(#) == -begin - character(cp) := character(#); - font(cp) := font(#); - do_subst_font(cp, 1000); - if font(cp) <> font(#) then - margin_kern_stretch := margin_kern_stretch + left_pw(#) - left_pw(cp); - font(cp) := font(#); - do_subst_font(cp, -1000); - if font(cp) <> font(#) then - margin_kern_shrink := margin_kern_shrink + left_pw(cp) - left_pw(#); -end - -@<Calculate variations of marginal kerns@>= -begin - lp := last_leftmost_char; - rp := last_rightmost_char; - fast_get_avail(cp); - if lp <> null then - cal_margin_kern_var(lp); - if rp <> null then - cal_margin_kern_var(rp); - free_avail(cp); -end - -@ Here is |hpack|, which is place where we do font substituting when -font expansion is being used. We define some constants used when calling -|hpack| to deal with font expansion. - -@d cal_expand_ratio == 2 {calculate amount for font expansion after breaking - paragraph into lines} -@d subst_ex_font == 3 {substitute fonts} - -@d substituted = 3 {|subtype| of kern nodes that should be substituted} - -@d left_pw(#) == char_pw(#, left_side) -@d right_pw(#) == char_pw(#, right_side) - -@p -function check_expand_pars(f: internal_font_number): boolean; -var k: internal_font_number; -begin - check_expand_pars := false; - if (pdf_font_step[f] = 0) or ((pdf_font_stretch[f] = null_font) and - (pdf_font_shrink[f] = null_font)) then - return; - if cur_font_step < 0 then - cur_font_step := pdf_font_step[f] - else if cur_font_step <> pdf_font_step[f] then - pdf_error("font expansion", "using fonts with different step of expansion in one paragraph is not allowed"); - k := pdf_font_stretch[f]; - if k <> null_font then begin - if max_stretch_ratio < 0 then - max_stretch_ratio := pdf_font_expand_ratio[k] - else if max_stretch_ratio <> pdf_font_expand_ratio[k] then - pdf_error("font expansion", "using fonts with different limit of expansion in one paragraph is not allowed"); - end; - k := pdf_font_shrink[f]; - if k <> null_font then begin - if max_shrink_ratio < 0 then - max_shrink_ratio := pdf_font_expand_ratio[k] - else if max_shrink_ratio <> pdf_font_expand_ratio[k] then - pdf_error("font expansion", "using fonts with different limit of expansion in one paragraph is not allowed"); - end; - check_expand_pars := true; -end; - -function char_stretch(f: internal_font_number; c: eight_bits): scaled; -var k: internal_font_number; - dw: scaled; - ef: integer; -begin - char_stretch := 0; - k := pdf_font_stretch[f]; - ef := get_ef_code(f, c); - if (k <> null_font) and (ef > 0) then begin - dw := char_width(k)(char_info(k)(c)) - char_width(f)(char_info(f)(c)); - if dw > 0 then - char_stretch := round_xn_over_d(dw, ef, 1000); - end; -end; - -function char_shrink(f: internal_font_number; c: eight_bits): scaled; -var k: internal_font_number; - dw: scaled; - ef: integer; -begin - char_shrink := 0; - k := pdf_font_shrink[f]; - ef := get_ef_code(f, c); - if (k <> null_font) and (ef > 0) then begin - dw := char_width(f)(char_info(f)(c)) - char_width(k)(char_info(k)(c)); - if dw > 0 then - char_shrink := round_xn_over_d(dw, ef, 1000); - end; -end; - -function get_kern(f: internal_font_number; lc, rc: eight_bits): scaled; -label continue; -var i: four_quarters; - j: four_quarters; - k: font_index; - p: pointer; - s: integer; -begin - get_kern := 0; - i := char_info(f)(lc); - if char_tag(i) <> lig_tag then - return; - k := lig_kern_start(f)(i); - j := font_info[k].qqqq; - if skip_byte(j) <= stop_flag then - goto continue + 1; - k := lig_kern_restart(f)(j); -continue: - j := font_info[k].qqqq; -continue + 1: - if (next_char(j) = rc) and (skip_byte(j) <= stop_flag) and - (op_byte(j) >= kern_flag) - then begin - get_kern := char_kern(f)(j); - return; - end; - if skip_byte(j) = qi(0) then - incr(k) - else begin - if skip_byte(j) >= stop_flag then - return; - k := k + qo(skip_byte(j)) + 1; - end; - goto continue; -end; - -function kern_stretch(p: pointer): scaled; -var l, r: pointer; - d: scaled; -begin - kern_stretch := 0; - if (prev_char_p = null) or (link(prev_char_p) <> p) or (link(p) = null) - then - return; - l := prev_char_p; - r := link(p); - if type(l) = ligature_node then - l := lig_char(l); - if type(r) = ligature_node then - r := lig_char(r); - if not (is_char_node(l) and is_char_node(r) and - (font(l) = font(r)) and - (pdf_font_stretch[font(l)] <> null_font)) - then - return; - d := get_kern(pdf_font_stretch[font(l)], character(l), character(r)); - kern_stretch := round_xn_over_d(d - width(p), - get_ef_code(font(l), character(l)), 1000); -end; - -function kern_shrink(p: pointer): scaled; -var l, r: pointer; - d: scaled; -begin - kern_shrink := 0; - if (prev_char_p = null) or (link(prev_char_p) <> p) or (link(p) = null) - then - return; - l := prev_char_p; - r := link(p); - if type(l) = ligature_node then - l := lig_char(l); - if type(r) = ligature_node then - r := lig_char(r); - if not (is_char_node(l) and is_char_node(r) and - (font(l) = font(r)) and - (pdf_font_shrink[font(l)] <> null_font)) - then - return; - d := get_kern(pdf_font_shrink[font(l)], character(l), character(r)); - kern_shrink := round_xn_over_d(width(p) - d, - get_ef_code(font(l), character(l)), 1000); -end; - -procedure do_subst_font(p: pointer; ex_ratio: integer); -var f, k: internal_font_number; - r: pointer; - ef: integer; -begin - if not is_char_node(p) and (type(p) = disc_node) then begin - r := pre_break(p); - while r <> null do begin - if is_char_node(r) or (type(r) = ligature_node) then - do_subst_font(r, ex_ratio); - r := link(r); - end; - r := post_break(p); - while r <> null do begin - if is_char_node(r) or (type(r) = ligature_node) then - do_subst_font(r, ex_ratio); - r := link(r); - end; - return; - end; - if is_char_node(p) then - r := p - else if type(p) = ligature_node then - r := lig_char(p) - else begin - {|short_display_n(p, 5);|} - pdf_error("font expansion", "invalid node type"); - end; - f := font(r); - ef := get_ef_code(f, character(r)); - if ef = 0 then - return; - if (pdf_font_stretch[f] <> null_font) and (ex_ratio > 0) then - k := expand_font(f, divide_scaled(ex_ratio* - pdf_font_expand_ratio[pdf_font_stretch[f]]*ef, - 1000000, 0)) - else if (pdf_font_shrink[f] <> null_font) and (ex_ratio < 0) then - k := expand_font(f, -divide_scaled(ex_ratio* - pdf_font_expand_ratio[pdf_font_shrink[f]]*ef, - 1000000, 0)) - else - k := f; - if k <> f then begin - font(r) := k; - if not is_char_node(p) then begin - r := lig_ptr(p); - while r <> null do begin - font(r) := k; - r := link(r); - end; - end; - end; -end; - -function char_pw(p: pointer; side: small_number): scaled; -var f: internal_font_number; - c: integer; -begin - char_pw := 0; - if side = left_side then - last_leftmost_char := null - else - last_rightmost_char := null; - if p = null then - return; - if not is_char_node(p) then begin - if type(p) = ligature_node then - p := lig_char(p) - else - return; - end; - f := font(p); - if side = left_side then begin - c := get_lp_code(f, character(p)); - last_leftmost_char := p; - end - else begin - c := get_rp_code(f, character(p)); - last_rightmost_char := p; - end; - if c = 0 then - return; - char_pw := - round_xn_over_d(quad(f), c, 1000); -end; - -function new_margin_kern(w: scaled; p: pointer; side: small_number): pointer; -var k: pointer; -begin - k := get_node(margin_kern_node_size); - type(k) := margin_kern_node; - subtype(k) := side; - width(k) := w; - if p = null then - pdf_error("margin kerning", "invalid pointer to marginal char node"); - fast_get_avail(margin_char(k)); - character(margin_char(k)) := character(p); - font(margin_char(k)) := font(p); - new_margin_kern := k; -end; - -function hpack(@!p:pointer;@!w:scaled;@!m:small_number):pointer; -@z - -@x [649] - font expansion -begin last_badness:=0; r:=get_node(box_node_size); type(r):=hlist_node; -subtype(r):=min_quarterword; shift_amount(r):=0; -q:=r+list_offset; link(q):=p;@/ -@y -font_stretch: scaled; -font_shrink: scaled; -k: scaled; -begin last_badness:=0; r:=get_node(box_node_size); type(r):=hlist_node; -subtype(r):=min_quarterword; shift_amount(r):=0; -q:=r+list_offset; link(q):=p;@/ -if m = cal_expand_ratio then begin - prev_char_p := null; - font_stretch := 0; - font_shrink := 0; - font_expand_ratio := 0; -end; -@z - -@x [649] - font expansion -hpack:=r; -@y -if (m = cal_expand_ratio) and (font_expand_ratio <> 0) then begin - font_expand_ratio := fix_int(font_expand_ratio, -1000, 1000); - q := list_ptr(r); - free_node(r, box_node_size); - r := hpack(q, w, subst_ex_font); -end; -hpack:=r; -@z - -@x [651] - font expansion - kern_node: x:=x+width(p); -@y - margin_kern_node: begin - if m = cal_expand_ratio then begin - f := font(margin_char(p)); - do_subst_font(margin_char(p), 1000); - if f <> font(margin_char(p)) then - font_stretch := font_stretch - width(p) - - char_pw(margin_char(p), subtype(p)); - font(margin_char(p)) := f; - do_subst_font(margin_char(p), -1000); - if f <> font(margin_char(p)) then - font_shrink := font_shrink - width(p) - - char_pw(margin_char(p), subtype(p)); - font(margin_char(p)) := f; - end - else if m = subst_ex_font then begin - do_subst_font(margin_char(p), font_expand_ratio); - width(p) := -char_pw(margin_char(p), subtype(p)); - end; - x := x + width(p); - end; - kern_node: begin - if (m = cal_expand_ratio) and (subtype(p) = normal) then begin - k := kern_stretch(p); - if k <> 0 then begin - subtype(p) := substituted; - font_stretch := font_stretch + k; - end; - k := kern_shrink(p); - if k <> 0 then begin - subtype(p) := substituted; - font_shrink := font_shrink + k; - end; - end - else if (m = subst_ex_font) and (subtype(p) = substituted) then begin - if type(link(p)) = ligature_node then - width(p) := get_kern(font(prev_char_p), - character(prev_char_p), - character(lig_char(link(p)))) - else - width(p) := get_kern(font(prev_char_p), - character(prev_char_p), - character(link(p))) - end; - x := x + width(p); - end; -@z - -@x [651] - font expansion - ligature_node: @<Make node |p| look like a |char_node| - and |goto reswitch|@>; -@y - ligature_node: begin - if m = subst_ex_font then - do_subst_font(p, font_expand_ratio); - @<Make node |p| look like a |char_node| and |goto reswitch|@>; - end; - disc_node: - if m = subst_ex_font then - do_subst_font(p, font_expand_ratio); -@z - -@x [654] - font expansion -begin f:=font(p); i:=char_info(f)(character(p)); hd:=height_depth(i); -@y -begin -if m >= cal_expand_ratio then begin - prev_char_p := p; - case m of - cal_expand_ratio: begin - f := font(p); - add_char_stretch(font_stretch)(character(p)); - add_char_shrink(font_shrink)(character(p)); - end; - subst_ex_font: - do_subst_font(p, font_expand_ratio); - endcases; -end; -f:=font(p); i:=char_info(f)(character(p)); hd:=height_depth(i); -@z - -@x [658] - font expansion -@ @<Determine horizontal glue stretch setting...@>= -begin @<Determine the stretch order@>; -@y -@ If |hpack| is called with |m=cal_expand_ratio| we calculate -|font_expand_ratio| and return without checking for overfull or underfull box. - -@<Determine horizontal glue stretch setting...@>= -begin @<Determine the stretch order@>; -if (m = cal_expand_ratio) and (o = normal) and (font_stretch > 0) then begin - font_expand_ratio := divide_scaled(x, font_stretch, 3); - return; -end; -@z - -@x [664] - font expansion -@ @<Determine horizontal glue shrink setting...@>= -begin @<Determine the shrink order@>; -@y -@ @<Determine horizontal glue shrink setting...@>= -begin @<Determine the shrink order@>; -if (m = cal_expand_ratio) and (o = normal) and (font_shrink > 0) then begin - font_expand_ratio := divide_scaled(x, font_shrink, 3); - return; -end; -@z - -@x [822] - font expansion -@d delta_node_size=7 {number of words in a delta node} -@y -@d delta_node_size=9 {number of words in a delta node} -@z - -@x [823] - font expansion, margin kerning, avoiding overfull boxes -@<Glo...@>= -@!active_width:array[1..6] of scaled; - {distance from first active node to~|cur_p|} -@!cur_active_width:array[1..6] of scaled; {distance from current active node} -@!background:array[1..6] of scaled; {length of an ``empty'' line} -@!break_width:array[1..6] of scaled; {length being computed after current break} -@y -@d do_seven_eight(#) == if pdf_adjust_spacing > 1 then begin #(7);#(8); end -@d do_all_eight(#) == do_all_six(#); do_seven_eight(#) -@d do_one_seven_eight(#) == #(1); do_seven_eight(#) - -@d total_font_stretch == cur_active_width[7] -@d total_font_shrink == cur_active_width[8] - -@d save_active_width(#) == prev_active_width[#] := active_width[#] -@d restore_active_width(#) == active_width[#] := prev_active_width[#] - -@<Glo...@>= -@!active_width:array[1..8] of scaled; - {distance from first active node to~|cur_p|} -@!cur_active_width:array[1..8] of scaled; {distance from current active node} -@!background:array[1..8] of scaled; {length of an ``empty'' line} -@!break_width:array[1..8] of scaled; {length being computed after current break} -@# -@!auto_breaking: boolean; {make |auto_breaking| accessible out of |line_break|} -@!prev_p: pointer; {make |prev_p| accessible out of |line_break|} -@!first_p: pointer; {to access the first node of the paragraph} -@!prev_char_p: pointer; {pointer to the previous char of an implicit kern} -@!next_char_p: pointer; {pointer to the next char of an implicit kern} -@# -@!try_prev_break: boolean; {force break at the previous legal breakpoint?} -@!prev_legal: pointer; {the previous legal breakpoint} -@!prev_prev_legal: pointer; {to save |prev_p| corresponding to |prev_legal|} -@!prev_auto_breaking: boolean; {to save |auto_breaking| corresponding to |prev_legal|} -@!prev_active_width: array[1..8] of scaled; {to save |active_width| corresponding to |prev_legal|} -@!rejected_cur_p: pointer; {the last |cur_p| that has been rejected} -@!before_rejected_cur_p: boolean; {|cur_p| is still before |rejected_cur_p|?} -@# -@!max_stretch_ratio: integer; {maximal stretch ratio of expanded fonts} -@!max_shrink_ratio: integer; {maximal shrink ratio of expanded fonts} -@!cur_font_step: integer; {the current step of expanded fonts} -@z - -@x [827] - font expansion -background[6]:=shrink(q)+shrink(r); -@y -background[6]:=shrink(q)+shrink(r); -if pdf_adjust_spacing > 1 then begin - background[7] := 0; - background[8] := 0; - max_stretch_ratio := -1; - max_shrink_ratio := -1; - cur_font_step := -1; - prev_char_p := null; -end; -@z - -@x [829] - margin kerning -@<Declare subprocedures for |line_break|@>= -procedure try_break(@!pi:integer;@!break_type:small_number); -@y -@d cp_skipable(#) == {skipable nodes at the margins during character protrusion} -( - not is_char_node(#) and - ( - (type(#) = ins_node) - or (type(#) = mark_node) - or (type(#) = adjust_node) - or (type(#) = penalty_node) - or ((type(#) = whatsit_node) and - (subtype(#) <> pdf_refximage_node) and - (subtype(#) <> pdf_refxform_node)) {reference to an image or XObject form} - or ((type(#) = disc_node) and - (pre_break(#) = null) and - (post_break(#) = null) and - (replace_count(#) = 0)) {an empty |disc_node|} - or ((type(#) = math_node) and (width(#) = 0)) - or ((type(#) = kern_node) and - ((width(#) = 0) or (subtype(#) = normal))) - or ((type(#) = glue_node) and (glue_ptr(#) = zero_glue)) - or ((type(#) = hlist_node) and (width(#) = 0) and (height(#) = 0) and - (depth(#) = 0) and (list_ptr(#) = null)) - ) -) - - -@<Declare subprocedures for |line_break|@>= -procedure push_node(p: pointer); -begin - if hlist_stack_level > max_hlist_stack then - pdf_error("push_node", "stack overflow"); - hlist_stack[hlist_stack_level] := p; - hlist_stack_level := hlist_stack_level + 1; -end; - -function pop_node: pointer; -begin - hlist_stack_level := hlist_stack_level - 1; - if hlist_stack_level < 0 then {would point to some bug} - pdf_error("pop_node", "stack underflow (internal error)"); - pop_node := hlist_stack[hlist_stack_level]; -end; - -function find_protchar_left(l: pointer; d: boolean): pointer; -{searches left to right from list head |l|, returns 1st non-skipable item} -var t: pointer; - run: boolean; -begin - if (link(l) <> null) and (type(l) = hlist_node) and (width(l) = 0) - and (height(l) = 0) and (depth(l) = 0) and (list_ptr(l) = null) then - l := link(l) {for paragraph start with \.{\\parindent = 0pt}} - else if d then - while (link(l) <> null) and (not (is_char_node(l) or non_discardable(l))) do - l := link(l); {std.\ discardables at line break, \TeX book, p 95} - hlist_stack_level := 0; - run := true; - repeat - t := l; - while run and (type(l) = hlist_node) and (list_ptr(l) <> null) do begin - push_node(l); - l := list_ptr(l); - end; - while run and cp_skipable(l) do begin - while (link(l) = null) and (hlist_stack_level > 0) do begin - l := pop_node; {don't visit this node again} - end; - if link(l) <> null then - l := link(l) - else if hlist_stack_level = 0 then run := false - end; - until t = l; - find_protchar_left := l; -end; - -function find_protchar_right(l, r: pointer): pointer; -{searches right to left from list tail |r| to head |l|, returns 1st non-skipable item} -var t: pointer; - run: boolean; -begin - find_protchar_right := null; - if r = null then return; - hlist_stack_level := 0; - run := true; - repeat - t := r; - while run and (type(r) = hlist_node) and (list_ptr(r) <> null) do begin - push_node(l); - push_node(r); - l := list_ptr(r); - r := l; - while link(r) <> null do - r := link(r); - end; - while run and cp_skipable(r) do begin - while (r = l) and (hlist_stack_level > 0) do begin - r := pop_node; {don't visit this node again} - l := pop_node; - end; - if (r <> l) and (r <> null) then - r := prev_rightmost(l, r) - else if (r = l) and (hlist_stack_level = 0) then run := false - end; - until t = r; - find_protchar_right := r; -end; - -function total_pw(q, p: pointer): scaled; -{returns the total width of character protrusion of a line; -|cur_break(break_node(q))| and |p| is the leftmost resp. rightmost node in the -horizontal list representing the actual line} -var l, r, s: pointer; - n: integer; -begin - if break_node(q) = null then - l := first_p - else - l := cur_break(break_node(q)); - r := prev_rightmost(prev_p, p); {get |link(r)=p|} - {let's look at the right margin first} - {| - short_display_n(r, 2); - print("&"); - short_display_n(p, 2); - print_ln; - |} - if (p <> null) and (type(p) = disc_node) and (pre_break(p) <> null) then - {a |disc_node| with non-empty |pre_break|, protrude the last char of |pre_break|} - begin - r := pre_break(p); - while link(r) <> null do - r := link(r); - end else r := find_protchar_right(l, r); - {now the left margin} - {| - short_display_n(l, 2); - print_ln; - breadth_max := 10; - depth_threshold := 2; - show_node_list(l); - print_ln; - |} - if (l <> null) and (type(l) = disc_node) then begin - if post_break(l) <> null then begin - l := post_break(l); {protrude the first char} - goto done; - end else {discard |replace_count(l)| nodes} - begin - n := replace_count(l); - l := link(l); - while n > 0 do begin - if link(l) <> null then - l := link(l); - decr(n); - end; - end; - end; - l := find_protchar_left(l, true); -done: - total_pw := left_pw(l) + right_pw(r); -end; - -procedure try_break(@!pi:integer;@!break_type:small_number); -@z - -@x -var r:pointer; {runs through the active list} -@y -var r:pointer; {runs through the active list} -@!margin_kern_stretch: scaled; -@!margin_kern_shrink: scaled; -@!lp, rp, cp: pointer; -@z - - -@x [829] - font expansion -do_all_six(copy_to_cur_active); -@y -do_all_eight(copy_to_cur_active); -@z - -@x [832] - font expansion - begin do_all_six(update_width); -@y - begin do_all_eight(update_width); -@z - -@x [837] - font expansion -begin no_break_yet:=false; do_all_six(set_break_width_to_background); -@y -begin no_break_yet:=false; do_all_eight(set_break_width_to_background); -@z - -@x [839] - font expansion -@<Glob...@>= -@!disc_width:scaled; {the length of discretionary material preceding a break} -@y -@d reset_disc_width(#) == disc_width[#] := 0 - -@d add_disc_width_to_break_width(#) == - break_width[#] := break_width[#] + disc_width[#] - -@d add_disc_width_to_active_width(#) == - active_width[#] := active_width[#] + disc_width[#] - -@d sub_disc_width_from_active_width(#) == - active_width[#] := active_width[#] - disc_width[#] - -@d add_char_stretch_end(#) == char_stretch(f, #) -@d add_char_stretch(#) == # := # + add_char_stretch_end - -@d add_char_shrink_end(#) == char_shrink(f, #) -@d add_char_shrink(#) == # := # + add_char_shrink_end - -@d sub_char_stretch_end(#) == char_stretch(f, #) -@d sub_char_stretch(#) == # := # - sub_char_stretch_end - -@d sub_char_shrink_end(#) == char_shrink(f, #) -@d sub_char_shrink(#) == # := # - sub_char_shrink_end - -@d add_kern_stretch_end(#) == kern_stretch(#) -@d add_kern_stretch(#) == # := # + add_kern_stretch_end - -@d add_kern_shrink_end(#) == kern_shrink(#) -@d add_kern_shrink(#) == # := # + add_kern_shrink_end - -@d sub_kern_stretch_end(#) == kern_stretch(#) -@d sub_kern_stretch(#) == # := # - sub_kern_stretch_end - -@d sub_kern_shrink_end(#) == kern_shrink(#) -@d sub_kern_shrink(#) == # := # - sub_kern_shrink_end - -@<Glob...@>= -@!disc_width: array[1..8] of scaled; {the length of discretionary material preceding a break} -@z - -@x [840] - font expansion -break_width[1]:=break_width[1]+disc_width; -@y -do_one_seven_eight(add_disc_width_to_break_width); -@z - -@x [841] - font expansion - break_width[1]:=break_width[1]-char_width(f)(char_info(f)(character(v))); -@y - break_width[1]:=break_width[1]-char_width(f)(char_info(f)(character(v))); - if (pdf_adjust_spacing > 1) and check_expand_pars(f) then begin - prev_char_p := v; - sub_char_stretch(break_width[7])(character(v)); - sub_char_shrink(break_width[8])(character(v)); - end; -@z - -@x [841] - font expansion - break_width[1]:=@|break_width[1]- - char_width(f)(char_info(f)(character(lig_char(v)))); -@y - break_width[1]:=@|break_width[1]- - char_width(f)(char_info(f)(character(lig_char(v)))); - if (pdf_adjust_spacing > 1) and check_expand_pars(f) then begin - prev_char_p := v; - sub_char_stretch(break_width[7])(character(lig_char(v))); - sub_char_shrink(break_width[8])(character(lig_char(v))); - end; -@z - -@x [841] - font expansion - hlist_node,vlist_node,rule_node,kern_node: - break_width[1]:=break_width[1]-width(v); -@y - hlist_node,vlist_node,rule_node,kern_node: begin - break_width[1]:=break_width[1]-width(v); - if (type(v) = kern_node) and - (pdf_adjust_spacing > 1) and (subtype(v) = normal) - then begin - sub_kern_stretch(break_width[7])(v); - sub_kern_shrink(break_width[8])(v); - end; - end; -@z - -@x [842] - font expansion - break_width[1]:=@|break_width[1]+char_width(f)(char_info(f)(character(s))); -@y - break_width[1]:=@|break_width[1]+char_width(f)(char_info(f)(character(s))); - if (pdf_adjust_spacing > 1) and check_expand_pars(f) then begin - prev_char_p := s; - add_char_stretch(break_width[7])(character(s)); - add_char_shrink(break_width[8])(character(s)); - end; -@z - -@x [842] - font expansion - break_width[1]:=break_width[1]+ - char_width(f)(char_info(f)(character(lig_char(s)))); -@y - break_width[1]:=break_width[1]+ - char_width(f)(char_info(f)(character(lig_char(s)))); - if (pdf_adjust_spacing > 1) and check_expand_pars(f) then begin - prev_char_p := s; - add_char_stretch(break_width[7])(character(lig_char(s))); - add_char_shrink(break_width[8])(character(lig_char(s))); - end; -@z - -@x [842] - font expansion - hlist_node,vlist_node,rule_node,kern_node: - break_width[1]:=break_width[1]+width(s); -@y - hlist_node,vlist_node,rule_node,kern_node: begin - break_width[1]:=break_width[1]+width(s); - if (type(s) = kern_node) and - (pdf_adjust_spacing > 1) and (subtype(s) = normal) - then begin - add_kern_stretch(break_width[7])(s); - add_kern_shrink(break_width[8])(s); - end; - end; -@z - -@x [843] - font expansion - begin do_all_six(convert_to_break_width); -@y - begin do_all_eight(convert_to_break_width); -@z - -@x [843] - font expansion - begin do_all_six(store_break_width); -@y - begin do_all_eight(store_break_width); -@z - -@x [843] - font expansion - do_all_six(new_delta_to_break_width); -@y - do_all_eight(new_delta_to_break_width); -@z - -@x [844] - font expansion - do_all_six(new_delta_from_break_width); -@y - do_all_eight(new_delta_from_break_width); -@z - -@x [851] - font expansion, margin kerning -shortfall:=line_width-cur_active_width[1]; {we're this much too short} -@y -shortfall:=line_width-cur_active_width[1]; {we're this much too short} - -{| -if pdf_output > 2 then begin -print_ln; -if (r <> null) and (break_node(r) <> null) then - short_display_n(cur_break(break_node(r)), 5); -print_ln; -short_display_n(cur_p, 5); -print_ln; -end; -|} - -if pdf_protrude_chars > 1 then - shortfall := shortfall + total_pw(r, cur_p); -if (pdf_adjust_spacing > 1) and (shortfall <> 0) then begin - margin_kern_stretch := 0; - margin_kern_shrink := 0; - if pdf_protrude_chars > 1 then - @<Calculate variations of marginal kerns@>; - if (shortfall > 0) and ((total_font_stretch + margin_kern_stretch) > 0) - then begin - if (total_font_stretch + margin_kern_stretch) > shortfall then - shortfall := ((total_font_stretch + margin_kern_stretch) div - (max_stretch_ratio div cur_font_step)) div 2 - else - shortfall := shortfall - (total_font_stretch + margin_kern_stretch); - end - else if (shortfall < 0) and ((total_font_shrink + margin_kern_shrink) > 0) - then begin - if (total_font_shrink + margin_kern_shrink) > -shortfall then - shortfall := -((total_font_shrink + margin_kern_shrink) div - (max_shrink_ratio div cur_font_step)) div 2 - else - shortfall := shortfall + (total_font_shrink + margin_kern_shrink); - end; -end; -@z - -@x [860] - font expansion - begin do_all_six(downdate_width); -@y - begin do_all_eight(downdate_width); -@z - -@x [860] - font expansion - begin do_all_six(update_width); - do_all_six(combine_two_deltas); -@y - begin do_all_eight(update_width); - do_all_eight(combine_two_deltas); -@z - -@x [861] - font expansion - begin do_all_six(update_active); - do_all_six(copy_to_cur_active); -@y - begin do_all_eight(update_active); - do_all_eight(copy_to_cur_active); -@z - -@x [862] - margin kerning, avoiding overfull boxes -@!auto_breaking:boolean; {is node |cur_p| outside a formula?} -@!prev_p:pointer; {helps to determine when glue nodes are breakpoints} -@y -@z - -@x [863] - margin kerning, avoiding overfull boxes - while (cur_p<>null)and(link(active)<>last_active) do -@y - prev_char_p := null; - prev_legal := null; - rejected_cur_p := null; - try_prev_break := false; - before_rejected_cur_p := false; - first_p := cur_p; {to access the first node of paragraph as the first active - node has |break_node=null|} - while (cur_p<>null)and(link(active)<>last_active) do -@z - -@x [864] - font expansion -do_all_six(store_background);@/ -@y -do_all_eight(store_background);@/ -@z - -@x [666] - font expansion - else act_width:=act_width+width(cur_p); -@y - else begin - act_width:=act_width+width(cur_p); - if (pdf_adjust_spacing > 1) and (subtype(cur_p) = normal) then begin - add_kern_stretch(active_width[7])(cur_p); - add_kern_shrink(active_width[8])(cur_p); - end; - end; -@z - -@x [866] - font expansion - act_width:=act_width+char_width(f)(char_info(f)(character(lig_char(cur_p)))); -@y - act_width:=act_width+char_width(f)(char_info(f)(character(lig_char(cur_p)))); - if (pdf_adjust_spacing > 1) and check_expand_pars(f) then begin - prev_char_p := cur_p; - add_char_stretch(active_width[7])(character(lig_char(cur_p))); - add_char_shrink(active_width[8])(character(lig_char(cur_p))); - end; -@z - -@x [867] - font expansion -act_width:=act_width+char_width(f)(char_info(f)(character(cur_p))); -@y -act_width:=act_width+char_width(f)(char_info(f)(character(cur_p))); -if (pdf_adjust_spacing > 1) and check_expand_pars(f) then begin - prev_char_p := cur_p; - add_char_stretch(active_width[7])(character(cur_p)); - add_char_shrink(active_width[8])(character(cur_p)); -end; -@z - -@x [869] - font expansion -begin s:=pre_break(cur_p); disc_width:=0; -@y -begin s:=pre_break(cur_p); -do_one_seven_eight(reset_disc_width); -@z - -@x [869] - font expansion - act_width:=act_width+disc_width; - try_break(hyphen_penalty,hyphenated); - act_width:=act_width-disc_width; -@y - do_one_seven_eight(add_disc_width_to_active_width); - try_break(hyphen_penalty,hyphenated); - do_one_seven_eight(sub_disc_width_from_active_width); -@z - -@x [870] - font expansion - disc_width:=disc_width+char_width(f)(char_info(f)(character(s))); -@y - disc_width[1]:=disc_width[1]+char_width(f)(char_info(f)(character(s))); - if (pdf_adjust_spacing > 1) and check_expand_pars(f) then begin - prev_char_p := s; - add_char_stretch(disc_width[7])(character(s)); - add_char_shrink(disc_width[8])(character(s)); - end; -@z - -@x [870] - font expansion - disc_width:=disc_width+ - char_width(f)(char_info(f)(character(lig_char(s)))); -@y - disc_width[1]:=disc_width[1]+ - char_width(f)(char_info(f)(character(lig_char(s)))); - if (pdf_adjust_spacing > 1) and check_expand_pars(f) then begin - prev_char_p := s; - add_char_stretch(disc_width[7])(character(lig_char(s))); - add_char_shrink(disc_width[8])(character(lig_char(s))); - end; -@z - -@x [870] - font expansion - hlist_node,vlist_node,rule_node,kern_node: - disc_width:=disc_width+width(s); -@y - hlist_node,vlist_node,rule_node,kern_node: begin - disc_width[1]:=disc_width[1]+width(s); - if (type(s) = kern_node) and - (pdf_adjust_spacing > 1) and (subtype(s) = normal) - then begin - add_kern_stretch(disc_width[7])(s); - add_kern_shrink(disc_width[8])(s); - end; - end; -@z - -@x [871] - font expansion - act_width:=act_width+char_width(f)(char_info(f)(character(s))); -@y - act_width:=act_width+char_width(f)(char_info(f)(character(s))); - if (pdf_adjust_spacing > 1) and check_expand_pars(f) then begin - prev_char_p := s; - add_char_stretch(active_width[7])(character(s)); - add_char_shrink(active_width[8])(character(s)); - end; -@z - -@x [871] - font expansion - act_width:=act_width+ - char_width(f)(char_info(f)(character(lig_char(s)))); -@y - act_width:=act_width+ - char_width(f)(char_info(f)(character(lig_char(s)))); - if (pdf_adjust_spacing > 1) and check_expand_pars(f) then begin - prev_char_p := s; - add_char_stretch(active_width[7])(character(lig_char(s))); - add_char_shrink(active_width[8])(character(lig_char(s))); - end; -@z - -@x [871] - font expansion - hlist_node,vlist_node,rule_node,kern_node: - act_width:=act_width+width(s); -@y - hlist_node,vlist_node,rule_node,kern_node: begin - act_width:=act_width+width(s); - if (type(s) = kern_node) and - (pdf_adjust_spacing > 1) and (subtype(s) = normal) - then begin - add_kern_stretch(active_width[7])(s); - add_kern_shrink(active_width[8])(s); - end; - end; -@z - -@x [877] - margin kerning -var q,@!r,@!s:pointer; {temporary registers for list manipulation} -@y -var q,@!r,@!s:pointer; {temporary registers for list manipulation} - p, k: pointer; - w: scaled; - glue_break: boolean; {was a break at glue?} - ptmp: pointer; -@z - -@x [881] - margin kerning -q:=cur_break(cur_p); disc_break:=false; post_disc_break:=false; -@y -q:=cur_break(cur_p); disc_break:=false; post_disc_break:=false; -glue_break := false; -@z - -@x [881] - margin kerning - subtype(q):=right_skip_code+1; add_glue_ref(right_skip); - goto done; -@y - subtype(q):=right_skip_code+1; add_glue_ref(right_skip); - glue_break := true; - goto done; -@z - -@x [881] - margin kerning -@<Put the \(r)\.{\\rightskip} glue after node |q|@>; -done: -@y -done: - -{at this point |q| is the rightmost breakpoint; the only exception is the case -of a discretionary break with non-empty |pre_break|, then |q| has been changed -to the last node of the |pre_break| list} - -if pdf_protrude_chars > 0 then begin - if disc_break and (is_char_node(q) or (type(q) <> disc_node)) - {|q| has been reset to the last node of |pre_break|} - then begin - p := q; - ptmp := p; - end else begin - p := prev_rightmost(temp_head, q); {get |link(p) = q|} - ptmp := p; - p := find_protchar_right(temp_head, p); - end; - {| - short_display_n(p, 1); - print_ln; - |} - w := right_pw(p); - if w <> 0 then {we have found a marginal kern, append it after |ptmp|} - begin - k := new_margin_kern(-w, last_rightmost_char, right_side); - link(k) := link(ptmp); - link(ptmp) := k; - if (ptmp = q) then - q := link(q); - end; -end; - -{if |q| was not a breakpoint at glue and has been reset to |rightskip| then - we append |rightskip| after |q| now} -if not glue_break then begin - @<Put the \(r)\.{\\rightskip} glue after node |q|@>; -end; -@z - -@x [887] - margin kerning -if left_skip<>zero_glue then -@y -{at this point |q| is the leftmost node; all discardable nodes have been discarded} -if pdf_protrude_chars > 0 then begin - p := q; - p := find_protchar_left(p, false); {no more discardables} - w := left_pw(p); - if w <> 0 then begin - k := new_margin_kern(-w, last_leftmost_char, left_side); - link(k) := q; - q := k; - end; -end; -if left_skip<>zero_glue then -@z - -@x [889] - font expansion, pre vadjust -just_box:=hpack(q,cur_width,exactly); -@y -if pdf_adjust_spacing > 0 then - just_box := hpack(q, cur_width, cal_expand_ratio) -else - just_box := hpack(q, cur_width, exactly); -@z - -@x [1110] - margin kerning -var p:pointer; {the box} -@y -var p:pointer; {the box} - r: pointer; {to remove marginal kern nodes} -@z - -@x [1110] - margin kerning -while link(tail)<>null do tail:=link(tail); -@y -while link(tail) <> null do begin - r := link(tail); - if not is_char_node(r) and (type(r) = margin_kern_node) then begin - link(tail) := link(r); - free_avail(margin_char(r)); - free_node(r, margin_kern_node_size); - end; - tail:=link(tail); -end; -@z - -@x [1147] - margin kerning -ligature_node:@<Make node |p| look like a |char_node|...@>; -@y -ligature_node:@<Make node |p| look like a |char_node|...@>; -margin_kern_node: d:=width(p); -@z - -@x [1253] - font expansion -assign_font_int: begin n:=cur_chr; scan_font_ident; f:=cur_val; - scan_optional_equals; scan_int; - if n=0 then hyphen_char[f]:=cur_val@+else skew_char[f]:=cur_val; - end; -@y -assign_font_int: begin n:=cur_chr; scan_font_ident; f:=cur_val; - if n < lp_code_base then begin - scan_optional_equals; scan_int; - if n=0 then hyphen_char[f]:=cur_val@+else skew_char[f]:=cur_val; - end - else begin - scan_char_num; p := cur_val; - scan_optional_equals; scan_int; - case n of - lp_code_base: set_lp_code(f, p, cur_val); - rp_code_base: set_rp_code(f, p, cur_val); - ef_code_base: set_ef_code(f, p, cur_val); - end; - end; -end; -@z - -@x [1254] - font expansion -primitive("skewchar",assign_font_int,1); -@!@:skew_char_}{\.{\\skewchar} primitive@> -@y -primitive("skewchar",assign_font_int,1); -@!@:skew_char_}{\.{\\skewchar} primitive@> -primitive("lpcode",assign_font_int,lp_code_base); -@!@:lp_code_}{\.{\\lpcode} primitive@> -primitive("rpcode",assign_font_int,rp_code_base); -@!@:rp_code_}{\.{\\rpcode} primitive@> -primitive("efcode",assign_font_int,ef_code_base); -@!@:ef_code_}{\.{\\efcode} primitive@> -@z - -@x [1255] - font expansion -assign_font_int: if chr_code=0 then print_esc("hyphenchar") - else print_esc("skewchar"); -@y -assign_font_int: case chr_code of -0: print_esc("hyphenchar"); -1: print_esc("skewchar"); -lp_code_base: print_esc("lpcode"); -rp_code_base: print_esc("rpcode"); -ef_code_base: print_esc("efcode"); -endcases; -@z - -@x [1344] -@d pdftex_last_extension_code == pdftex_first_extension_code + 27 -@y -@d pdf_font_expand_code == pdftex_first_extension_code + 28 -@d pdftex_last_extension_code == pdftex_first_extension_code + 28 -@z - -@x [1344] -primitive("setlanguage",extension,set_language_code);@/ -@!@:set_language_}{\.{\\setlanguage} primitive@> -@y -primitive("setlanguage",extension,set_language_code);@/ -@!@:set_language_}{\.{\\setlanguage} primitive@> -primitive("pdffontexpand",extension,pdf_font_expand_code);@/ -@!@:pdf_font_expand_}{\.{\\pdffontexpand} primitive@> -@z - -@x [1346] - immediate_code:print_esc("immediate"); - set_language_code:print_esc("setlanguage"); -@y - immediate_code:print_esc("immediate"); - set_language_code:print_esc("setlanguage"); - pdf_font_expand_code: print_esc("pdffontexpand"); -@z - -@x [1348] -set_language_code:@<Implement \.{\\setlanguage}@>; -@y -set_language_code:@<Implement \.{\\setlanguage}@>; -pdf_font_expand_code: @<Implement \.{\\pdffontexpand}@>; -@z - -@x [1354] -@<Implement \.{\\special}@>= -begin new_whatsit(special_node,write_node_size); write_stream(tail):=null; -p:=scan_toks(false,true); write_tokens(tail):=def_ref; -end -@y -@<Implement \.{\\special}@>= -begin new_whatsit(special_node,write_node_size); write_stream(tail):=null; -p:=scan_toks(false,true); write_tokens(tail):=def_ref; -end - -@ @<Implement \.{\\pdffontexpand}@>= - read_expand_font -@z - -@x [15??] -@<Declare procedures that need to be declared forward for pdftex@>= -@y -@<Declare procedures that need to be declared forward for pdftex@>= -function prev_rightmost(s, e: pointer): pointer; -{finds the node preceding the rightmost node |e|; |s| is some node -before |e|} -var p: pointer; -begin - prev_rightmost := null; - p := s; - if p = null then - return; - while link(p) <> e do begin - p := link(p); - if p = null then - return; - end; - prev_rightmost := p; -end; -@z - |