summaryrefslogtreecommitdiff
path: root/Build/source/texk/web2c/pdftexdir/pdftex.ch
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/texk/web2c/pdftexdir/pdftex.ch')
-rw-r--r--Build/source/texk/web2c/pdftexdir/pdftex.ch7055
1 files changed, 333 insertions, 6722 deletions
diff --git a/Build/source/texk/web2c/pdftexdir/pdftex.ch b/Build/source/texk/web2c/pdftexdir/pdftex.ch
index 6ae23335465..31211b2477f 100644
--- a/Build/source/texk/web2c/pdftexdir/pdftex.ch
+++ b/Build/source/texk/web2c/pdftexdir/pdftex.ch
@@ -1,32 +1,5 @@
-% WEB change file containing code for pdfTeX features extending TeX; % to be applied to tex.web (Version 3.141592) in order to define the
-% pdfTeX program.
%
-% Note: This file, pdftex.ch, defines pdftex.web in terms of changes to be
-% applied to tex.web; in terms of a program such as TIE (or equivalent),
-%
-% tex.web )
-% + ) => tie -m ... => etex.web
-% pdftexdir/pdftex.ch )
-%
-% In addition, this file is used to define pdfetex.web, a combination
-% of e-TeX and pdfTeX as follows:
-%
-% tex.web )
-% + )
-% etexdir/etex.ch )
-% + )
-% pdfetexdir/pdfetex.ch1 ) => tie -m ... => pdfetex.web
-% + )
-% pdftexdir/pdftex.ch )
-% + )
-% pdfetexdir/pdfetex.ch2 )
-%
-% where the two (small) files pdfetexdir/pdfetex.ch[12] take care of
-% interferences between e-Tex changes (etexdir/etex.ch) and pdfTeX changes
-% (pdftexdir/pdftex.ch). Consequently, changes in these files have to be
-% coordinated.
-%
-% Copyright (c) 1996-2005 Han Th\^e\llap{\raise 0.5ex\hbox{\'{}}} Th\`anh, <thanh@pdftex.org>
+% Copyright (c) 1996-2006 Han The Thanh, <thanh@pdftex.org>
%
% This file is part of pdfTeX.
%
@@ -44,708 +17,83 @@
% 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/pdftex.ch#171 $
+% $Id: //depot/Build/source.development/TeX/texk/web2c/pdfetexdir/pdfetex.ch2#20 $
%
-% The TeX program is copyright (C) 1982 by D. E. Knuth.
-% TeX is a trademark of the American Mathematical Society.
-%
-% all pdfTeX new primitives have the prefix "\pdf", apart from:
-% o extension of \vadjust
-% o extension of \font
-% o \efcode
-% o \lpcode, \rpcode
-% o \leftmarginkern, \rightmarginkern
-
-@x limbo
-\def\PASCAL{Pascal}
-@y
-\def\PASCAL{Pascal}
-\def\pdfTeX{pdf\TeX}
-\def\PDF{PDF}
-@z
-
-@x [2] - This change is made for TeX 3.141592
-@d banner=='This is TeX, Version 3.141592' {printed when \TeX\ starts}
-@y
-@d pdftex_version==130 { \.{\\pdftexversion} }
-@d pdftex_revision=="4" { \.{\\pdftexrevision} }
-@d pdftex_version_string=='-1.30.4' {current \pdfTeX\ version}
-@#
-@d pdfTeX_banner=='This is pdfTeX, Version 3.141592',pdftex_version_string
- {printed when \pdfTeX\ starts}
-@#
-@d TeX_banner=='This is TeX, Version 3.141592' {printed when \TeX\ starts}
-@#
-@d banner==pdfTeX_banner
+@x [0.0] l.83 - WEAVE: we want the whole file
+ \def\?##1]{\hbox{Changes to \hbox to 1em{\hfil##1}.\ }}
+ }
+\let\maybe=\iffalse
+@y 83
+ \def\?##1]{\hbox{Changes to \hbox to 1em{\hfil##1}.\ }}
+ }
+\let\maybe=\iftrue
@z
-% Some procedures that need to be declared forward
-@x [173]
-@* \[12] Displaying boxes.
-@y
-@<Declare procedures that need to be declared forward for pdftex@>@;
-
-@* \[12] Displaying boxes.
-@z
+% Change file to assist in creating the web2c-specific change file.
+% This one resolves inconsistencies between tex.ch and tex.ech.
+% Public domain.
-% Define pdftex token list parameters
-@x [230]
-@d toks_base=local_base+10 {table of 256 token list registers}
+@x [1] m.2 l.188 - Web2C: extensions imply we're not e-TeX
+@d eTeX_banner=='This is e-TeX, Version 3.141592',eTeX_version_string
@y
-@d tex_toks=local_base+10 {end of \TeX's token list parameters}
-@#
-@d pdftex_first_loc = tex_toks {base for \pdfTeX's token list parameters}
-@d pdf_pages_attr_loc = pdftex_first_loc + 0 {points to token list for \.{\\pdfpagesattr}}
-@d pdf_page_attr_loc = pdftex_first_loc + 1 {points to token list for \.{\\pdfpageattr}}
-@d pdf_page_resources_loc = pdftex_first_loc + 2 {points to token list for \.{\\pdfpageresources}}
-@d pdf_pk_mode_loc = pdftex_first_loc + 3 {points to token list for \.{\\pdfpkmode}}
-@d pdf_toks=pdftex_first_loc+4 {end of \pdfTeX's token list parameters}
-@#
-@d toks_base=pdf_toks {table of 256 token list registers}
+@d eTeX_banner_k=='This is e-TeXk, Version 3.141592',eTeX_version_string
+@d eTeX_banner=='This is e-TeX, Version 3.141592',eTeX_version_string
@z
-@x [230]
-@d err_help==equiv(err_help_loc)
+@x [1] m.2 l.188 - Web2C: extensions imply we're not pdfeTeX
+@d pdfeTeX_banner=='This is pdfeTeX, Version 3.141592',pdftex_version_string,eTeX_version_string
@y
-@d err_help==equiv(err_help_loc)
-@d pdf_pages_attr==equiv(pdf_pages_attr_loc)
-@d pdf_page_attr==equiv(pdf_page_attr_loc)
-@d pdf_page_resources==equiv(pdf_page_resources_loc)
-@d pdf_pk_mode==equiv(pdf_pk_mode_loc)
+@d pdfeTeX_banner_k=='This is pdfeTeXk, Version 3.141592',pdftex_version_string,eTeX_version_string
+@d pdfeTeX_banner=='This is pdfeTeX, Version 3.141592',pdftex_version_string,eTeX_version_string
@z
-@x [230]
-primitive("errhelp",assign_toks,err_help_loc);
-@!@:err_help_}{\.{\\errhelp} primitive@>
-@y
-primitive("errhelp",assign_toks,err_help_loc);
-@!@:err_help_}{\.{\\errhelp} primitive@>
-primitive("pdfpagesattr",assign_toks,pdf_pages_attr_loc);
-@!@:pdf_pages_attr_}{\.{\\pdfpagesattr} primitive@>
-primitive("pdfpageattr",assign_toks,pdf_page_attr_loc);
-@!@:pdf_page_attr_}{\.{\\pdfpageattr} primitive@>
-primitive("pdfpageresources",assign_toks,pdf_page_resources_loc);
-@!@:pdf_page_resources_}{\.{\\pdfpageresources} primitive@>
-primitive("pdfpkmode",assign_toks,pdf_pk_mode_loc);
-@!@:pdf_pk_mode_}{\.{\\pdfpkmode} primitive@>
-@z
-
-@x [231]
- othercases print_esc("errhelp")
-@y
- pdf_pages_attr_loc: print_esc("pdfpagesattr");
- pdf_page_attr_loc: print_esc("pdfpageattr");
- pdf_page_resources_loc: print_esc("pdfpageresources");
- pdf_pk_mode_loc: print_esc("pdfpkmode");
- othercases print_esc("errhelp")
-@z
-
-% Define pdftex integer parameters
-@x [236]
-@d int_pars=55 {total number of integer parameters}
-@y
-@d tex_int_pars=55 {total number of \TeX's integer parameters}
-@#
-@d pdftex_first_integer_code = tex_int_pars {base for \pdfTeX's integer parameters}
-@d pdf_output_code = pdftex_first_integer_code + 0 {switch on PDF output if positive}
-@d pdf_compress_level_code = pdftex_first_integer_code + 1 {compress level of streams}
-@d pdf_decimal_digits_code = pdftex_first_integer_code + 2 {digits after the decimal point of numbers}
-@d pdf_move_chars_code = pdftex_first_integer_code + 3 {move chars 0..31 to higher area if possible}
-@d pdf_image_resolution_code = pdftex_first_integer_code + 4 {default image resolution}
-@d pdf_pk_resolution_code = pdftex_first_integer_code + 5 {default resolution of PK font}
-@d pdf_unique_resname_code = pdftex_first_integer_code + 6 {generate unique names for resouces}
-@d pdf_option_always_use_pdfpagebox_code = pdftex_first_integer_code + 7 {if the pdf inclusion should always use a specific pdf page box}
-@d pdf_option_pdf_inclusion_errorlevel_code = pdftex_first_integer_code + 8 {if the pdf inclusion should treat pdfs newer than |pdf_minor_version| as an error}
-@d pdf_minor_version_code = pdftex_first_integer_code + 9 {fractional part of the pdf version produced}
-@d pdf_force_pagebox_code = pdftex_first_integer_code + 10 {if the pdf inclusion should always use a specific pdf page box}
-@d pdf_inclusion_errorlevel_code = pdftex_first_integer_code + 11 {if the pdf inclusion should treat pdfs newer than |pdf_minor_version| as an error}
-@d pdf_gamma_code = pdftex_first_integer_code + 12
-@d pdf_image_gamma_code = pdftex_first_integer_code + 13
-@d pdf_image_hicolor_code = pdftex_first_integer_code + 14
-@d pdf_image_apply_gamma_code = pdftex_first_integer_code + 15
-@d pdf_px_dimen_code = pdftex_first_integer_code + 16 {the code for the pixel dimen value}
-@d pdf_int_pars=pdftex_first_integer_code + 17 {total number of \pdfTeX's integer parameters}
-@#
-@d int_pars=pdf_int_pars {total number of 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_output == int_par(pdf_output_code)
-@d pdf_compress_level == int_par(pdf_compress_level_code)
-@d pdf_decimal_digits == int_par(pdf_decimal_digits_code)
-@d pdf_move_chars == int_par(pdf_move_chars_code)
-@d pdf_image_resolution == int_par(pdf_image_resolution_code)
-@d pdf_pk_resolution == int_par(pdf_pk_resolution_code)
-@d pdf_unique_resname == int_par(pdf_unique_resname_code)
-@d pdf_option_always_use_pdfpagebox == int_par(pdf_option_always_use_pdfpagebox_code)
-@d pdf_option_pdf_inclusion_errorlevel == int_par(pdf_option_pdf_inclusion_errorlevel_code)
-@d pdf_minor_version == int_par(pdf_minor_version_code)
-@d pdf_force_pagebox == int_par(pdf_force_pagebox_code)
-@d pdf_inclusion_errorlevel == int_par(pdf_inclusion_errorlevel_code)
-@d pdf_gamma == int_par(pdf_gamma_code)
-@d pdf_image_gamma == int_par(pdf_image_gamma_code)
-@d pdf_image_hicolor == int_par(pdf_image_hicolor_code)
-@d pdf_image_apply_gamma == int_par(pdf_image_apply_gamma_code)
-@d pdf_px_dimen == int_par(pdf_px_dimen_code)
-@z
-
-@x [237]
-error_context_lines_code:print_esc("errorcontextlines");
-@y
-error_context_lines_code:print_esc("errorcontextlines");
-@#
-pdf_output_code: print_esc("pdfoutput");
-pdf_compress_level_code: print_esc("pdfcompresslevel");
-pdf_decimal_digits_code: print_esc("pdfdecimaldigits");
-pdf_move_chars_code: print_esc("pdfmovechars");
-pdf_image_resolution_code: print_esc("pdfimageresolution");
-pdf_pk_resolution_code: print_esc("pdfpkresolution");
-pdf_unique_resname_code: print_esc("pdfuniqueresname");
-pdf_option_always_use_pdfpagebox_code: print_esc("pdfoptionalwaysusepdfpagebox");
-pdf_option_pdf_inclusion_errorlevel_code: print_esc("pdfoptionpdfinclusionerrorlevel");
-pdf_minor_version_code: print_esc("pdfminorversion");
-pdf_force_pagebox_code: print_esc("pdfforcepagebox");
-pdf_inclusion_errorlevel_code: print_esc("pdfinclusionerrorlevel");
-pdf_gamma_code: print_esc("pdfgamma");
-pdf_image_gamma_code: print_esc("pdfimagegamma");
-pdf_image_hicolor_code: print_esc("pdfimagehicolor");
-pdf_image_apply_gamma_code: print_esc("pdfimageapplygamma");
-pdf_px_dimen_code: print_esc("pdfpxdimen");
-@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("pdfoutput",assign_int,int_base+pdf_output_code);@/
-@!@:pdf_output_}{\.{\\pdfoutput} primitive@>
-primitive("pdfcompresslevel",assign_int,int_base+pdf_compress_level_code);@/
-@!@:pdf_compress_level_}{\.{\\pdfcompresslevel} primitive@>
-primitive("pdfdecimaldigits",assign_int,int_base+pdf_decimal_digits_code);@/
-@!@:pdf_decimal_digits_}{\.{\\pdfdecimaldigits} primitive@>
-primitive("pdfmovechars",assign_int,int_base+pdf_move_chars_code);@/
-@!@:pdf_move_chars_}{\.{\\pdfmovechars} primitive@>
-primitive("pdfimageresolution",assign_int,int_base+pdf_image_resolution_code);@/
-@!@:pdf_image_resolution_}{\.{\\pdfimageresolution} primitive@>
-primitive("pdfpkresolution",assign_int,int_base+pdf_pk_resolution_code);@/
-@!@:pdf_pk_resolution_}{\.{\\pdfpkresolution} primitive@>
-primitive("pdfuniqueresname",assign_int,int_base+pdf_unique_resname_code);@/
-@!@:pdf_unique_resname_}{\.{\\pdfuniqueresname} primitive@>
-primitive("pdfoptionpdfminorversion",assign_int,int_base+pdf_minor_version_code);@/
-@!@:pdf_minor_version_}{\.{\\pdfoptionpdfminorversion} primitive@>
-primitive("pdfoptionalwaysusepdfpagebox",assign_int,int_base+pdf_option_always_use_pdfpagebox_code);@/
-@!@:pdf_option_always_use_pdfpagebox_}{\.{\\pdfoptionalwaysusepdfpagebox} primitive@>
-primitive("pdfoptionpdfinclusionerrorlevel",assign_int,int_base+pdf_option_pdf_inclusion_errorlevel_code);@/
-@!@:pdf_option_pdf_inclusion_errorlevel_}{\.{\\pdfoptionpdfinclusionerrorlevel} primitive@>
-primitive("pdfminorversion",assign_int,int_base+pdf_minor_version_code);@/
-@!@:pdf_minor_version_}{\.{\\pdfminorversion} primitive@>
-primitive("pdfforcepagebox",assign_int,int_base+pdf_force_pagebox_code);@/
-@!@:pdf_force_pagebox_}{\.{\\pdfforcepagebox} primitive@>
-primitive("pdfinclusionerrorlevel",assign_int,int_base+pdf_inclusion_errorlevel_code);@/
-@!@:pdf_inclusion_errorlevel_}{\.{\\pdfinclusionerrorlevel} primitive@>
-primitive("pdfgamma",assign_int,int_base+pdf_gamma_code);@/
-@!@:pdf_gamma_}{\.{\\pdfgamma} primitive@>
-primitive("pdfimagegamma",assign_int,int_base+pdf_image_gamma_code);@/
-@!@:pdf_image_gamma_}{\.{\\pdfimagegamma} primitive@>
-primitive("pdfimagehicolor",assign_int,int_base+pdf_image_hicolor_code);@/
-@!@:pdf_image_hicolor_}{\.{\\pdfimagehicolor} primitive@>
-primitive("pdfimageapplygamma",assign_int,int_base+pdf_image_apply_gamma_code);@/
-@!@:pdf_image_apply_gamma_}{\.{\\pdfimageapplygamma} primitive@>
-primitive("pdfpxdimen",assign_int,int_base+pdf_px_dimen_code);@/
-@!@:pdf_px_dimen_}{\.{\\pdfpxdimen} primitive@>
-@z
-
-@x [240] - pxdimen
-for k:=int_base to del_code_base-1 do eqtb[k].int:=0;
+@x [1] m.2 l.188 - Web2C: extensions imply we're not pdfTeX
+@d pdfTeX_banner=='This is pdfTeX, Version 3.141592',pdftex_version_string
@y
-for k:=int_base to del_code_base-1 do eqtb[k].int:=0;
-pdf_px_dimen := unity;
+@d pdfTeX_banner_k=='This is pdfTeXk, Version 3.141592',pdftex_version_string
+@d pdfTeX_banner=='This is pdfTeX, Version 3.141592',pdftex_version_string
@z
-% Define pdftex dimension parameters
-@x [247]
-@d emergency_stretch_code=20 {reduces badnesses on final pass of line-breaking}
+@x [1] m.2 l.188 - banner
+@d banner==TeX_banner
+@d banner_k==TeX_banner_k
@y
-@d emergency_stretch_code=20 {reduces badnesses on final pass of line-breaking}
-@d pdftex_first_dimen_code = 21 {first number defined in this section}
-@d pdf_h_origin_code = pdftex_first_dimen_code + 0 {horigin of the PDF output}
-@d pdf_v_origin_code = pdftex_first_dimen_code + 1 {vorigin of the PDF output}
-@d pdf_page_width_code = pdftex_first_dimen_code + 2 {page width of the PDF output}
-@d pdf_page_height_code = pdftex_first_dimen_code + 3 {page height of the PDF output}
-@d pdf_link_margin_code = pdftex_first_dimen_code + 4 {link margin in the PDF output}
-@d pdf_dest_margin_code = pdftex_first_dimen_code + 5 {dest margin in the PDF output}
-@d pdf_thread_margin_code = pdftex_first_dimen_code + 6 {thread margin in the PDF output}
-@d pdf_first_line_height_code = pdftex_first_dimen_code + 7
-@d pdf_last_line_depth_code = pdftex_first_dimen_code + 8
-@d pdf_each_line_height_code = pdftex_first_dimen_code + 9
-@d pdf_each_line_depth_code = pdftex_first_dimen_code + 10
-@d pdftex_last_dimen_code = pdftex_first_dimen_code + 10 {last number defined in this section}
+@d banner==pdfTeX_banner
+@d banner_k==pdfTeX_banner_k
@z
@x
-@d dimen_pars=21 {total number of dimension parameters}
+@d frozen_null_font=frozen_control_sequence+11
+ {permanent `\.{\\nullfont}'}
@y
-@d dimen_pars = pdftex_last_dimen_code + 1 {total number of dimension parameters}
+@d frozen_null_font=frozen_control_sequence+12
+ {permanent `\.{\\nullfont}'}
@z
-@x [247]
-@d emergency_stretch==dimen_par(emergency_stretch_code)
-@y
-@d emergency_stretch==dimen_par(emergency_stretch_code)
-@d pdf_h_origin == dimen_par(pdf_h_origin_code)
-@d pdf_v_origin == dimen_par(pdf_v_origin_code)
-@d pdf_page_width == dimen_par(pdf_page_width_code)
-@d pdf_page_height == dimen_par(pdf_page_height_code)
-@d pdf_link_margin == dimen_par(pdf_link_margin_code)
-@d pdf_dest_margin == dimen_par(pdf_dest_margin_code)
-@d pdf_thread_margin == dimen_par(pdf_thread_margin_code)
-@d pdf_first_line_height == dimen_par(pdf_first_line_height_code)
-@d pdf_last_line_depth == dimen_par(pdf_last_line_depth_code)
-@d pdf_each_line_height == dimen_par(pdf_each_line_height_code)
-@d pdf_each_line_depth == dimen_par(pdf_each_line_depth_code)
-@z
-
-@x [247]
-emergency_stretch_code:print_esc("emergencystretch");
-@y
-emergency_stretch_code:print_esc("emergencystretch");
-pdf_h_origin_code: print_esc("pdfhorigin");
-pdf_v_origin_code: print_esc("pdfvorigin");
-pdf_page_width_code: print_esc("pdfpagewidth");
-pdf_page_height_code: print_esc("pdfpageheight");
-pdf_link_margin_code: print_esc("pdflinkmargin");
-pdf_dest_margin_code: print_esc("pdfdestmargin");
-pdf_thread_margin_code: print_esc("pdfthreadmargin");
-pdf_first_line_height_code: print_esc("pdffirstlineheight");
-pdf_last_line_depth_code: print_esc("pdflastlinedepth");
-pdf_each_line_height_code: print_esc("pdfeachlineheight");
-pdf_each_line_depth_code: print_esc("pdfeachlinedepth");
-@z
-
-@x [248]
-primitive("emergencystretch",assign_dimen,dimen_base+emergency_stretch_code);@/
-@!@:emergency_stretch_}{\.{\\emergencystretch} primitive@>
-@y
-primitive("emergencystretch",assign_dimen,dimen_base+emergency_stretch_code);@/
-@!@:emergency_stretch_}{\.{\\emergencystretch} primitive@>
-primitive("pdfhorigin",assign_dimen,dimen_base+pdf_h_origin_code);@/
-@!@:pdf_h_origin_}{\.{\\pdfhorigin} primitive@>
-primitive("pdfvorigin",assign_dimen,dimen_base+pdf_v_origin_code);@/
-@!@:pdf_v_origin_}{\.{\\pdfvorigin} primitive@>
-primitive("pdfpagewidth",assign_dimen,dimen_base+pdf_page_width_code);@/
-@!@:pdf_page_width_}{\.{\\pdfpagewidth} primitive@>
-primitive("pdfpageheight",assign_dimen,dimen_base+pdf_page_height_code);@/
-@!@:pdf_page_height_}{\.{\\pdfpageheight} primitive@>
-primitive("pdflinkmargin",assign_dimen,dimen_base+pdf_link_margin_code);@/
-@!@:pdf_link_margin_}{\.{\\pdflinkmargin} primitive@>
-primitive("pdfdestmargin",assign_dimen,dimen_base+pdf_dest_margin_code);@/
-@!@:pdf_dest_margin_}{\.{\\pdfdestmargin} primitive@>
-primitive("pdfthreadmargin",assign_dimen,dimen_base+pdf_thread_margin_code);@/
-@!@:pdf_thread_margin_}{\.{\\pdfthreadmargin} primitive@>
-primitive("pdffirstlineheight",assign_dimen,dimen_base+pdf_first_line_height_code);@/
-@!@:pdf_first_line_height_}{\.{\\pdffirstlineheight} primitive@>
-primitive("pdflastlinedepth",assign_dimen,dimen_base+pdf_last_line_depth_code);@/
-@!@:pdf_last_line_depth_}{\.{\\pdflastlinedepth} primitive@>
-primitive("pdfeachlineheight",assign_dimen,dimen_base+pdf_each_line_height_code);@/
-@!@:pdf_each_line_height_}{\.{\\pdfeachlineheight} primitive@>
-primitive("pdfeachlinedepth",assign_dimen,dimen_base+pdf_each_line_depth_code);@/
-@!@:pdf_each_line_depth_}{\.{\\pdfeachlinedepth} primitive@>
-@z
-
-% Define some read-only pdfTeX primitives
-@x [416]
-|glue_val|, |input_line_no_code|, or |badness_code|.
-@y
-|glue_val|, |input_line_no_code|, or |badness_code|.
-\pdfTeX\ adds the codes for its extensions: |pdftex_version_code|, \dots\ .
-@z
-
-@x [416]
-@d badness_code=glue_val+2 {code for \.{\\badness}}
-@y
-@d badness_code=input_line_no_code+1 {code for \.{\\badness}}
+@x [17.236] l.4960 - first web2c, then e-TeX additional integer parameters
+@d int_pars=web2c_int_pars {total number of integer parameters}
@#
-@d pdftex_first_rint_code = badness_code + 1 {base for \pdfTeX's command codes}
-@d pdftex_version_code = pdftex_first_rint_code + 0 {code for \.{\\pdftexversion}}
-@d pdf_last_obj_code = pdftex_first_rint_code + 1 {code for \.{\\pdflastobj}}
-@d pdf_last_xform_code = pdftex_first_rint_code + 2 {code for \.{\\pdflastxform}}
-@d pdf_last_ximage_code = pdftex_first_rint_code + 3 {code for \.{\\pdflastximage}}
-@d pdf_last_ximage_pages_code = pdftex_first_rint_code + 4 {code for \.{\\pdflastximagepages}}
-@d pdf_last_annot_code = pdftex_first_rint_code + 5 {code for \.{\\pdflastannot}}
-@d pdf_last_x_pos_code = pdftex_first_rint_code + 6 {code for \.{\\pdflastxpos}}
-@d pdf_last_y_pos_code = pdftex_first_rint_code + 7 {code for \.{\\pdflastypos}}
-@d pdf_retval_code = pdftex_first_rint_code + 8 {global multi-purpose return value}
-@d pdf_last_ximage_colordepth_code = pdftex_first_rint_code + 9 {code for \.{\\pdflastximagecolordepth}}
-@d elapsed_time_code = pdftex_first_rint_code + 10 {code for \.{\\pdfelapsedtime}}
-@d pdftex_last_item_codes = pdftex_first_rint_code + 10 {end of \pdfTeX's command codes}
-@z
-
-@x [416]
-primitive("badness",last_item,badness_code);
-@!@:badness_}{\.{\\badness} primitive@>
-@y
-primitive("badness",last_item,badness_code);
-@!@:badness_}{\.{\\badness} primitive@>
-primitive("pdftexversion",last_item,pdftex_version_code);@/
-@!@:pdftex_version_}{\.{\\pdftexversion} primitive@>
-primitive("pdflastobj",last_item,pdf_last_obj_code);@/
-@!@:pdf_last_obj_}{\.{\\pdflastobj} primitive@>
-primitive("pdflastxform",last_item,pdf_last_xform_code);@/
-@!@:pdf_last_xform_}{\.{\\pdflastxform} primitive@>
-primitive("pdflastximage",last_item,pdf_last_ximage_code);@/
-@!@:pdf_last_ximage_}{\.{\\pdflastximage} primitive@>
-primitive("pdflastximagepages",last_item,pdf_last_ximage_pages_code);@/
-@!@:pdf_last_ximage_pages_}{\.{\\pdflastximagepages} primitive@>
-primitive("pdflastannot",last_item,pdf_last_annot_code);@/
-@!@:pdf_last_annot_}{\.{\\pdflastannot} primitive@>
-primitive("pdflastxpos",last_item,pdf_last_x_pos_code);@/
-@!@:pdf_last_x_pos_}{\.{\\pdflastxpos} primitive@>
-primitive("pdflastypos",last_item,pdf_last_y_pos_code);@/
-@!@:pdf_last_y_pos_}{\.{\\pdflastypos} primitive@>
-primitive("pdfretval",last_item,pdf_retval_code);@/
-@!@:pdf_retval_}{\.{\\pdfretval} primitive@>
-primitive("pdflastximagecolordepth",last_item,pdf_last_ximage_colordepth_code);@/
-@!@:pdf_last_ximage_colordepth_}{\.{\\pdflastximagecolordepth} primitive@>
-primitive("pdfelapsedtime",last_item,elapsed_time_code);
-@!@:elapsed_time_}{\.{\\pdfelapsedtime} primitive@>
-@z
-
-@x [417]
- othercases print_esc("badness")
-@y
- pdftex_version_code: print_esc("pdftexversion");
- pdf_last_obj_code: print_esc("pdflastobj");
- pdf_last_xform_code: print_esc("pdflastxform");
- pdf_last_ximage_code: print_esc("pdflastximage");
- pdf_last_ximage_pages_code: print_esc("pdflastximagepages");
- pdf_last_annot_code: print_esc("pdflastannot");
- pdf_last_x_pos_code: print_esc("pdflastxpos");
- pdf_last_y_pos_code: print_esc("pdflastypos");
- pdf_retval_code: print_esc("pdfretval");
- pdf_last_ximage_colordepth_code: print_esc("pdflastximagecolordepth");
- elapsed_time_code: print_esc("pdfelapsedtime");
- othercases print_esc("badness")
-@z
-
-@x [424]
-if cur_chr>glue_val then
-@y
-if m>=input_line_no_code then
-@z
-
-@x [424]
- begin if cur_chr=input_line_no_code then cur_val:=line
- else cur_val:=last_badness; {|cur_chr=badness_code|}
-@y
- begin case m of
- input_line_no_code: cur_val:=line;
- badness_code: cur_val:=last_badness;
- pdftex_version_code: cur_val := pdftex_version;
- pdf_last_obj_code: cur_val := pdf_last_obj;
- pdf_last_xform_code: cur_val := pdf_last_xform;
- pdf_last_ximage_code: cur_val := pdf_last_ximage;
- pdf_last_ximage_pages_code: cur_val := pdf_last_ximage_pages;
- pdf_last_annot_code: cur_val := pdf_last_annot;
- pdf_last_x_pos_code: cur_val := pdf_last_x_pos;
- pdf_last_y_pos_code: cur_val := pdf_last_y_pos;
- pdf_retval_code: cur_val := pdf_retval;
- pdf_last_ximage_colordepth_code: cur_val := pdf_last_ximage_colordepth;
- elapsed_time_code: cur_val := get_microinterval;
- end; {there are no other cases}
-@z
-
-@x [455] - pxdimen
-else if scan_keyword("ex") then v:=(@<The x-height for |cur_font|@>)
-@.ex@>
-@y
-else if scan_keyword("ex") then v:=(@<The x-height for |cur_font|@>)
-@.ex@>
-else if scan_keyword("px") then v:=pdf_px_dimen
-@.px@>
-@z
-
-@x new Didot (1nd=0.375mm), new Cicero (1nc=12nd)
-@ The necessary conversion factors can all be specified exactly as
-fractions whose numerator and denominator are 32768 or less.
-According to the definitions here, $\rm2660\,dd\approx1000.33297\,mm$;
-this agrees well with the value $\rm1000.333\,mm$ cited by Bosshard
-@^Bosshard, Hans Rudolf@>
-in {\sl Technische Grundlagen zur Satzherstellung\/} (Bern, 1980).
-@y
-@ The necessary conversion factors can all be specified exactly as
-fractions whose numerator and denominator are 65535 or less.
-According to the definitions here, $\rm2660\,dd\approx1000.33297\,mm$;
-this agrees well with the value $\rm1000.333\,mm$ cited by Bosshard
-@^Bosshard, Hans Rudolf@>
-in {\sl Technische Grundlagen zur Satzherstellung\/} (Bern, 1980).
-The Didot point has been newly standardized in 1978;
-it's now exactly $\rm 1\,nd=0.375\,mm$.
-Conversion uses the equation $0.375=21681/20320/72.27\cdot25.4$.
-The new Cicero follows the new Didot point; $\rm 1\,nc=12\,nd$.
-@z
-
-@x new Didot (1nd=0.375mm), new Cicero (1nc=12nd)
-else if scan_keyword("cc") then set_conversion(14856)(1157)
-@.cc@>
+@d etex_int_base=tex_int_pars {base for \eTeX's integer parameters}
@y
-else if scan_keyword("cc") then set_conversion(14856)(1157)
-@.cc@>
-else if scan_keyword("nd") then set_conversion(21681)(20320)
-@.nd@>
-else if scan_keyword("nc") then set_conversion(65043)(5080)
-@.nc@>
+@d pdftex_first_integer_code = web2c_int_pars {base for \pdfTeX's integer parameters}
@z
-@x new Didot (1nd=0.375mm), new Cicero (1nc=12nd)
- ("cm, mm, dd, cc, bp, or sp; but yours is a new one!")@/
-@y
- ("cm, mm, dd, cc, nd, nc, bp, or sp; but yours is a new one!")@/
-@z
-
-% Define some char token producing pdfTeX primitives
-@x [468]
-@d number_code=0 {command code for \.{\\number}}
-@y
-\pdfTeX\ adds \.{\\eTeXrevision}, \.{\\pdftexrevision}, \.{\\pdftexbanner},
-\.{\\pdffontname}, \.{\\pdffontobjnum}, \.{\\pdffontsize}, and \.{\\pdfpageref}
-such that |job_name_code| remains last.
-
-@d number_code=0 {command code for \.{\\number}}
-@z
-
-@x [468]
-@d job_name_code=5 {command code for \.{\\jobname}}
-@y
-@d pdftex_first_expand_code = 5 {base for \pdfTeX's command codes}
-@d pdftex_revision_code = pdftex_first_expand_code + 0 {command code for \.{\\pdftexrevision}}
-@d pdftex_banner_code = pdftex_first_expand_code + 1 {command code for \.{\\pdftexbanner}}
-@d pdf_font_name_code = pdftex_first_expand_code + 2 {command code for \.{\\pdffontname}}
-@d pdf_font_objnum_code = pdftex_first_expand_code + 3 {command code for \.{\\pdffontobjnum}}
-@d pdf_font_size_code = pdftex_first_expand_code + 4 {command code for \.{\\pdffontsize}}
-@d pdf_page_ref_code = pdftex_first_expand_code + 5 {command code for \.{\\pdfpageref}}
-@d pdf_xform_name_code = pdftex_first_expand_code + 6 {command code for \.{\\pdfxformname}}
-@d pdf_last_escaped_string_code = pdftex_first_expand_code + 7 {command code for \.{\\pdflastescapedstring}}
-@d pdf_last_escaped_name_code = pdftex_first_expand_code + 8 {command code for \.{\\pdflastescapename}}
-@d pdftex_convert_codes = pdftex_first_expand_code + 9 {end of \pdfTeX's command codes}
-@d job_name_code=pdftex_convert_codes {command code for \.{\\jobname}}
-@z
-
-@x [468]
-primitive("jobname",convert,job_name_code);@/
-@y
-@#
-primitive("pdftexrevision",convert,pdftex_revision_code);@/
-@!@:pdftex_revision_}{\.{\\pdftexrevision} primitive@>
-primitive("pdftexbanner",convert,pdftex_banner_code);@/
-@!@:pdftex_banner_}{\.{\\pdftexbanner} primitive@>
-primitive("pdffontname",convert,pdf_font_name_code);@/
-@!@:pdf_font_name_}{\.{\\pdffontname} primitive@>
-primitive("pdffontobjnum",convert,pdf_font_objnum_code);@/
-@!@:pdf_font_objnum_}{\.{\\pdffontobjnum} primitive@>
-primitive("pdffontsize",convert,pdf_font_size_code);@/
-@!@:pdf_font_size_}{\.{\\pdffontsize} primitive@>
-primitive("pdfpageref",convert,pdf_page_ref_code);@/
-@!@:pdf_page_ref_}{\.{\\pdfpageref} primitive@>
-primitive("pdfxformname",convert,pdf_xform_name_code);@/
-@!@:pdf_xform_name_}{\.{\\pdfxformname} primitive@>
-primitive("pdflastescapedstring",convert,pdf_last_escaped_string_code);@/
-@!@:pdf_last_escaped_string_}{\.{\\pdflastescapedstring} primitive@>
-primitive("pdflastescapedname",convert,pdf_last_escaped_name_code);@/
-@!@:pdf_last_escaped_name_}{\.{\\pdflastescapedname} primitive@>
-@#
-primitive("jobname",convert,job_name_code);@/
-@z
-
-@x [469]
- othercases print_esc("jobname")
-@y
- pdftex_revision_code: print_esc("pdftexrevision");
- pdftex_banner_code: print_esc("pdftexbanner");
- pdf_font_name_code: print_esc("pdffontname");
- pdf_font_objnum_code: print_esc("pdffontobjnum");
- pdf_font_size_code: print_esc("pdffontsize");
- pdf_page_ref_code: print_esc("pdfpageref");
- pdf_xform_name_code: print_esc("pdfxformname");
- pdf_last_escaped_string_code: print_esc("pdflastescapedstring");
- pdf_last_escaped_name_code: print_esc("pdflastescapedname");
- othercases print_esc("jobname")
-@z
-
-@x [465] - pdfescapestring
-@!b:pool_pointer; {base of temporary string}
-@y
-@!b:pool_pointer; {base of temporary string}
-@!i, l: integer; {index to access escaped string or name}
-@z
-
-@x [471]
-job_name_code: if job_name=0 then open_log_file;
-@y
-pdftex_revision_code: do_nothing;
-pdftex_banner_code: do_nothing;
-pdf_font_name_code, pdf_font_objnum_code, pdf_font_size_code: begin
- scan_font_ident;
- if cur_val = null_font then
- pdf_error("font", "invalid font identifier");
- if c <> pdf_font_size_code then begin
- pdf_check_vf(cur_val);
- if not font_used[cur_val] then
- pdf_init_font(cur_val);
- end;
-end;
-pdf_page_ref_code: begin
- scan_int;
- if cur_val <= 0 then
- pdf_error("pageref", "invalid page number");
-end;
-pdf_xform_name_code: begin
- scan_int;
- pdf_check_obj(obj_type_xform, cur_val);
-end;
-pdf_last_escaped_string_code: do_nothing;
-pdf_last_escaped_name_code: do_nothing;
-job_name_code: if job_name=0 then open_log_file;
-@z
-
-@x [472]
-job_name_code: print(job_name);
-@y
-pdftex_revision_code: print(pdftex_revision);
-pdftex_banner_code: print(pdftex_banner);
-pdf_font_name_code, pdf_font_objnum_code: begin
- set_ff(cur_val);
- if c = pdf_font_name_code then
- print_int(obj_info(pdf_font_num[ff]))
- else
- print_int(pdf_font_num[ff]);
-end;
-pdf_font_size_code: begin
- print_scaled(font_size[cur_val]);
- print("pt");
-end;
-pdf_page_ref_code: print_int(get_obj(obj_type_page, cur_val, false));
-pdf_xform_name_code: print_int(obj_info(cur_val));
-pdf_last_escaped_string_code: begin
- l := escapedstrlen;
- for i := 0 to l - 1 do
- print_char(getescapedstrchar(i));
-end;
-pdf_last_escaped_name_code: begin
- l := escapednamelen;
- for i := 0 to l - 1 do
- print_char(getescapednamechar(i));
-end;
-job_name_code: print(job_name);
-@z
-
-@x [577] - tagcode
-@<Declare procedures that scan font-related stuff@>=
-procedure scan_font_ident;
-@y
-@<Declare procedures that scan font-related stuff@>=
-function get_tag_code(f: internal_font_number; c: eight_bits): integer;
-var i:small_number;
-begin
- if is_valid_char(c) then
+% start of tex.pch
+@x (MLTeX) l. 12945
begin i := char_tag(char_info(f)(c));
- if i = lig_tag then
- get_tag_code := 1
- else if i = list_tag then
- get_tag_code := 2
- else if i = ext_tag then
- get_tag_code := 4
- else
- get_tag_code := 0;
- end
- else
- get_tag_code := -1;
-end;
-procedure scan_font_ident;
-@z
-
-% Shipping out to PDF
-@x [638]
-@ The |hlist_out| and |vlist_out| procedures are now complete, so we are
-ready for the |ship_out| routine that gets them started in the first place.
-
-@p procedure ship_out(@!p:pointer); {output the box |p|}
@y
-@ The |hlist_out| and |vlist_out| procedures are now complete, so we are
-ready for the |dvi_ship_out| routine that gets them started in the first place.
-
-@p procedure dvi_ship_out(@!p:pointer); {output the box |p|}
+ begin i := char_tag(orig_char_info(f)(c));
@z
-@x [644]
-@* \[33] Packaging.
-@y
-
-@* \[32a] \pdfTeX\ basic.
-
-Initialize pdftex's parameters to some useful default value.
-Helpful in case one forgets to set them during initex run.
-
-@<Initialize table entries...@>=
-pdf_h_origin := (one_hundred_inch + 50) div 100;
-pdf_v_origin := (one_hundred_inch + 50) div 100;
-pdf_compress_level := 9;
-pdf_decimal_digits := 4;
-pdf_image_resolution := 72;
-pdf_minor_version := 4;
-pdf_gamma := 1000;
-pdf_image_gamma := 2200;
-pdf_image_hicolor := 1;
-pdf_image_apply_gamma := 0;
-
-@ The subroutines define the corresponding macros so we can use them
-in C.
-
-@d flushable(#) == (# = str_ptr - 1)
-
-@d is_valid_char(#)==((font_bc[f] <= #) and (# <= font_ec[f]) and
+@x (MLTeX) l. 14640
+@d is_valid_char(#)==((font_bc[f] <= #) and (# <= font_ec[f]) and
char_exists(char_info(f)(#)))
+@y
+@d is_valid_char(#)==((font_bc[f] <= #) and (# <= font_ec[f]) and
+ char_exists(orig_char_info(f)(#)))
+@z
-@p function get_pdf_compress_level: integer;
-begin
- get_pdf_compress_level := pdf_compress_level;
-end;
-
-function get_nullfont: internal_font_number;
-begin
- get_nullfont := null_font;
-end;
-
-function get_nullcs: pointer;
-begin
- get_nullcs := null_cs;
-end;
-
-function get_nullptr: pointer;
-begin
- get_nullptr := null;
-end;
-
-function get_tex_int(code: integer): integer;
-begin
- get_tex_int := int_par(code);
-end;
-
-function get_tex_dimen(code: integer): scaled;
-begin
- get_tex_dimen := dimen_par(code);
-end;
-
-function get_x_height(f: internal_font_number): scaled;
-begin
- get_x_height := x_height(f);
-end;
-
+@x (MLTeX) l. 14678
function get_charwidth(f: internal_font_number; c: eight_bits): scaled;
begin
if is_valid_char(c) then
@@ -769,6085 +117,348 @@ begin
else
get_chardepth := 0;
end;
-
-function get_quad(f: internal_font_number): scaled;
-begin
- get_quad := quad(f);
-end;
-
-function get_slant(f: internal_font_number): scaled;
-begin
- get_slant := slant(f);
-end;
-
-function new_dummy_font: internal_font_number;
-begin
- new_dummy_font := read_font_info(null_cs, "dummy", "", -1000);
-end;
-
-@ Helper for debugging purposes
-
-@p procedure short_display_n(@!p, m:integer); {prints highlights of list |p|}
-var n:integer; {for replacement counts}
- i: integer;
-begin
-i := 0;
-font_in_short_display:=null_font;
-if p = null then
- return;
-while p>mem_min do
- begin if is_char_node(p) then
- begin if p<=mem_end then
- begin if font(p)<>font_in_short_display then
- begin if (font(p)<font_base)or(font(p)>font_max) then
- print_char("*")
-@.*\relax@>
- else @<Print the font identifier for |font(p)|@>;
- print_char(" "); font_in_short_display:=font(p);
- end;
- print_ASCII(qo(character(p)));
- end;
- end
- else begin
- if (type(p) = glue_node) or
- (type(p) = disc_node) or
- (type(p) = penalty_node) or
- ((type(p) = kern_node) and (subtype(p) = explicit)) then
- incr(i);
- if i >= m then
- return;
- if (type(p) = disc_node) then begin
- print("|");
- short_display(pre_break(p));
- print("|");
- short_display(post_break(p));
- print("|");
- n:=replace_count(p);
- while n>0 do
- begin if link(p)<>null then p:=link(p);
- decr(n);
- end;
- end
- else
- @<Print a short indication of the contents of node |p|@>;
- end;
- p:=link(p);
- if p = null then
- return;
- end;
- update_terminal;
-end;
-
-@ Sometimes it is neccesary to allocate memory for PDF output that cannot
-be deallocated then, so we use |pdf_mem| for this purpose.
-
-@<Constants...@>=
-@!inf_pdf_mem_size = 10000; {min size of the |pdf_mem| array}
-@!sup_pdf_mem_size = 10000000; {max size of the |pdf_mem| array}
-
-@ @<Glob...@>=
-@!pdf_mem_size: integer;
-@!pdf_mem: ^integer;
-@!pdf_mem_ptr: integer;
-
-@ @<Set init...@>=
-pdf_mem_ptr := 1; {the first word is not used so we can use zero as a value for testing
-whether a pointer to |pdf_mem| is valid}
-pdf_mem_size := inf_pdf_mem_size; {allocated size of |pdf_mem| array}
-
-@ We use |pdf_get_mem| to allocate memory in |pdf_mem|
-
-@p function pdf_get_mem(s: integer): integer; {allocate |s| words in |pdf_mem|}
-var a: integer;
-begin
- if s > sup_pdf_mem_size - pdf_mem_size then
- overflow("PDF memory size (pdf_mem_size)", pdf_mem_size);
- if pdf_mem_ptr + s > pdf_mem_size then begin
- a := 0.2 * pdf_mem_size;
- if pdf_mem_ptr + s > pdf_mem_size + a then
- pdf_mem_size := pdf_mem_ptr + s
- else if pdf_mem_size < sup_pdf_mem_size - a then
- pdf_mem_size := pdf_mem_size + a
- else
- pdf_mem_size := sup_pdf_mem_size;
- pdf_mem := xrealloc_array(pdf_mem, integer, pdf_mem_size);
- end;
- pdf_get_mem := pdf_mem_ptr;
- pdf_mem_ptr := pdf_mem_ptr + s;
-end;
-
-@* \[32b] \pdfTeX\ output low-level subroutines.
-We use the similiar subroutines to handle the output buffer for
-PDF output. When compress is used, the state of writing to buffer
-is held in |zip_write_state|. We must write the header of PDF
-output file in initialization to ensure that it will be the first
-written bytes.
-
-@<Constants...@>=
-@!pdf_buf_size = 16384; {size of the PDF buffer}
-
-@ The following macros are similar as for \.{DVI} buffer handling
-
-@d pdf_offset == (pdf_gone + pdf_ptr) {the file offset of last byte in PDF
-buffer that |pdf_ptr| points to}
-
-@d no_zip == 0 {no \.{ZIP} compression}
-@d zip_writing == 1 {\.{ZIP} compression being used}
-@d zip_finish == 2 {finish \.{ZIP} compression}
-
-@d pdf_quick_out(#) == {output a byte to PDF buffer without checking of
-overflow}
-begin
- pdf_buf[pdf_ptr] := #;
- incr(pdf_ptr);
-end
-
-@d pdf_room(#) == {make sure that there are at least |n| bytes free in PDF
-buffer}
-begin
- if pdf_buf_size < # then
- overflow("PDF output buffer", pdf_buf_size);
- if pdf_ptr + # > pdf_buf_size then
- pdf_flush;
-end
-
-@d pdf_out(#) == {do the same as |pdf_quick_out| and flush the PDF
-buffer if necessary}
-begin
- if pdf_ptr > pdf_buf_size then
- pdf_flush;
- pdf_quick_out(#);
-end
-
-@<Glob...@>=
-@!pdf_file: byte_file; {the PDF output file}
-@!pdf_buf: array[0..pdf_buf_size] of eight_bits; {the PDF buffer}
-@!pdf_ptr: integer; {pointer to the first unused byte in the PDF buffer}
-@!pdf_gone: integer; {number of bytes that were flushed to output}
-@!pdf_save_offset: integer; {to save |pdf_offset|}
-@!zip_write_state: integer; {which state of compression we are in}
-@!fixed_pdf_minor_version: integer; {fixed minor part of the pdf version}
-@!pdf_minor_version_written: boolean; {flag if the pdf version has been written}
-@!fixed_pdfoutput: integer; {fixed output format}
-@!fixed_pdfoutput_set: boolean; {|fixed_pdfoutput| has been set?}
-@!fixed_gamma: integer;
-@!fixed_image_gamma: integer;
-@!fixed_image_hicolor: boolean;
-@!fixed_image_apply_gamma: integer;
-@!epochseconds: integer;
-@!microseconds: integer;
-
-@ @<Set init...@>=
-pdf_buf[0] := "%";
-pdf_buf[1] := "P";
-pdf_buf[2] := "D";
-pdf_buf[3] := "F";
-pdf_buf[4] := "-";
-pdf_buf[5] := "1";
-pdf_buf[6] := ".";
-pdf_buf[7] := "4";
-pdf_buf[8] := pdf_new_line_char;
-pdf_buf[9] := "%";
-pdf_buf[10] := 208;
-pdf_buf[11] := 212;
-pdf_buf[12] := 197;
-pdf_buf[13] := 216;
-pdf_buf[14] := pdf_new_line_char;
-pdf_ptr := 15;
-pdf_gone := 0;
-zip_write_state := no_zip;
-pdf_minor_version_written := false;
-fixed_pdfoutput_set := false;
-fixed_gamma := 1000;
-fixed_image_gamma := 2200;
-fixed_image_hicolor := 1;
-fixed_image_apply_gamma := 0;
-
-@ @p
-function fix_int(val, min, max: integer): integer;
-begin
- if val < min then
- fix_int := min
- else if val > max then
- fix_int := max
- else
- fix_int := val;
-end;
-
-@ This checks that |pdfminorversion| can only be set before any
-bytes have been written to the generated pdf file. It should be called
-directly after every |ensure_pdf_open|.
-
-@p procedure check_pdfminorversion;
-begin
- if not pdf_minor_version_written then begin
- pdf_minor_version_written := true;
- if (pdf_minor_version < 0) or (pdf_minor_version > 9) then begin
- print_err("pdfTeX error (illegal pdfminorversion)");
- print_ln;
- help2 ("The pdfminorversion must be between 0 and 9.")@/
- ("I changed this to 4.");
- int_error (pdf_minor_version);
- pdf_minor_version := 4;
- end;
- fixed_pdf_minor_version := pdf_minor_version;
- pdf_buf[7] := chr(ord("0") + fixed_pdf_minor_version);
- fixed_gamma := fix_int(pdf_gamma, 0, 1000000);
- fixed_image_gamma := fix_int(pdf_image_gamma, 0, 1000000);
- fixed_image_hicolor := fix_int(pdf_image_hicolor, 0, 1);
- fixed_image_apply_gamma := fix_int(pdf_image_apply_gamma, 0, 1);
- end
- else begin
- if fixed_pdf_minor_version <> pdf_minor_version then
- pdf_error("setup",
- "\pdfminorversion cannot be changed after data is written to the pdf file");
- end;
-end;
-
-@ Checks that we have a name for the generated pdf file and that it's open.
-|check_pdfminorversion| should be called directly
-hereafter.
-
-@p procedure ensure_pdf_open;
-begin
- if output_file_name <> 0 then
- return;
- if job_name = 0 then
- open_log_file;
- pack_job_name(".pdf");
- while not b_open_out(pdf_file) do
- prompt_file_name("file name for output",".pdf");
- output_file_name := b_make_name_string(pdf_file);
-end;
-
-@ The PDF buffer is flushed by calling |pdf_flush|, which checks the
-variable |zip_write_state| and will compress the buffer before flushing if
-neccesary. We call |pdf_begin_stream| to begin a stream and |pdf_end_stream|
-to finish it. The stream contents will be compressed if compression is turn on.
-
-@p procedure pdf_flush; {flush out the |pdf_buf|}
-begin
- ensure_pdf_open;
- check_pdfminorversion;
- case zip_write_state of
- no_zip: if pdf_ptr > 0 then begin
- write_pdf(0, pdf_ptr - 1);
- pdf_gone := pdf_gone + pdf_ptr;
- end;
- zip_writing:
- write_zip(false);
- zip_finish: begin
- write_zip(true);
- zip_write_state := no_zip;
- end;
- end;
- pdf_ptr := 0;
-end;
-
-procedure pdf_begin_stream; {begin a stream}
-begin
- ensure_pdf_open;
- check_pdfminorversion;
- pdf_print_ln("/Length ");
- pdf_stream_length_offset := pdf_offset - 11;
- pdf_stream_length := 0;
- if pdf_compress_level > 0 then begin
- pdf_print_ln("/Filter /FlateDecode");
- pdf_print_ln(">>");
- pdf_print_ln("stream");
- pdf_flush;
- zip_write_state := zip_writing;
- end
- else begin
- pdf_print_ln(">>");
- pdf_print_ln("stream");
- pdf_save_offset := pdf_offset;
- end;
-end;
-
-procedure pdf_end_stream; {end a stream}
-begin
- if pdf_compress_level > 0 then
- zip_write_state := zip_finish
- else
- pdf_stream_length := pdf_offset - pdf_save_offset;
- pdf_flush;
- write_stream_length(pdf_stream_length, pdf_stream_length_offset);
- if pdf_compress_level > 0 then
- pdf_out(pdf_new_line_char);
- pdf_print_ln("endstream");
- pdf_end_obj;
-end;
-
-@ Basic printing procedures for PDF output are very similiar to \TeX\ basic
-printing ones but the output is going to PDF buffer. Subroutines with
-suffix |_ln| append a new-line character to the PDF output.
-
-@d pdf_new_line_char == 10 {new-line character for UNIX platforms}
-
-@d pdf_print_nl == {output a new-line character to PDF buffer}
-if (pdf_ptr > 0) and (pdf_buf[pdf_ptr - 1] <> pdf_new_line_char) then
- pdf_out(pdf_new_line_char)
-
-@d pdf_print_ln(#) == {print out a string to PDF buffer followed by
-a new-line character}
-begin
- pdf_print(#);
- pdf_print_nl;
-end
-
-@d pdf_print_int_ln(#) == {print out an integer to PDF buffer followed by
-a new-line character}
-begin
- pdf_print_int(#);
- pdf_print_nl;
-end
-
-@<Declare procedures that need to be declared forward for pdftex@>=
-procedure pdf_error(t, p: str_number);
-begin
- normalize_selector;
- print_err("pdfTeX error");
- if t <> 0 then begin
- print(" (");
- print(t);
- print(")");
- end;
- print(": "); print(p);
- succumb;
-end;
-
-procedure pdf_warning(t, p: str_number; append_nl: boolean);
-begin
- print_err("pdfTeX warning");
- if t <> 0 then begin
- print(" (");
- print(t);
- print(")");
- end;
- print(": "); print(p);
- if append_nl then
- print_ln;
-end;
-
-procedure remove_last_space;
-begin
- if (pdf_ptr > 0) and (pdf_buf[pdf_ptr - 1] = 32) then
- decr(pdf_ptr);
-end;
-
-procedure pdf_print_octal(n: integer); {prints an integer in octal form to
-PDF buffer}
-var k:0..23; {index to current digit; we assume that $|n|<10^{23}$}
-begin
- k:=0;
- repeat dig[k]:=n mod 8; n:=n div 8; incr(k);
- until n=0;
- if k = 1 then begin
- pdf_out("0");
- pdf_out("0");
- end;
- if k = 2 then
- pdf_out("0");
- while k>0 do begin
- decr(k);
- pdf_out("0"+dig[k]);
- end;
-end;
-
-procedure pdf_print_char(f: internal_font_number; c: integer);
-{ print out a character to PDF buffer; the character will be printed in octal
- form in the following cases: chars <= 32, backslash (92), left parenthesis
- (40) and right parenthesis (41) }
-begin
- if c <= 32 then
- c := pdf_char_map[f, c];
- pdf_mark_char(f, c);
- if (c <= 32) or (c = 92) or (c = 40) or (c = 41) or (c > 127) then begin
- pdf_out(92); {output a backslash}
- pdf_print_octal(c);
- end
- else
- pdf_out(c);
-end;
-
-procedure pdf_print(s: str_number); {print out a string to PDF buffer}
-var j: pool_pointer; {current character code position}
- c: integer;
-begin
- j := str_start[s];
- while j < str_start[s + 1] do begin
- c := str_pool[j];
- pdf_out(c);
- incr(j);
- end;
-end;
-
-function str_in_str(s, r: str_number; i: integer): boolean;
- {test equality of strings}
-label not_found; {loop exit}
-var j, k: pool_pointer; {running indices}
-@!result: boolean; {result of comparison}
-begin
- str_in_str := false;
- if length(s) < i + length(r) then
- return;
- j := i + str_start[s];
- k := str_start[r];
- while (j < str_start[s + 1]) and (k < str_start[r + 1]) do begin
- if str_pool[j] <> str_pool[k] then
- return;
- incr(j);
- incr(k);
- end;
- str_in_str := true;
-end;
-
-procedure literal(s: str_number; literal_mode: integer; warn: boolean);
-var j: pool_pointer; {current character code position}
-begin
- j:=str_start[s];
- if literal_mode = scan_special then begin
- if not (str_in_str(s, "PDF:", 0) or str_in_str(s, "pdf:", 0)) then begin
- if warn and not (str_in_str(s, "SRC:", 0)
- or str_in_str(s, "src:", 0)
- or (length(s) = 0)) then
- print_nl("Non-PDF special ignored!");
- return;
- end;
- j := j + length("PDF:");
- if str_in_str(s, "direct:", length("PDF:")) then begin
- j := j + length("direct:");
- literal_mode := direct_always; end
- else if str_in_str(s, "page:", length("PDF:")) then begin
- j := j + length("page:");
- literal_mode := direct_page; end
- else
- literal_mode := reset_origin;
- end;
- case literal_mode of
- reset_origin: begin
- pdf_end_text;
- pdf_set_origin;
- end;
- direct_page:
- pdf_end_text;
- direct_always: begin
- pdf_first_space_corr := 0;
- pdf_end_string;
- pdf_print_nl;
- end;
- othercases confusion("literal1")
- endcases;
- while j<str_start[s+1] do begin
- pdf_out(str_pool[j]);
- incr(j);
- end;
- pdf_print_nl;
-end;
-
-procedure pdf_print_int(n:integer); {print out a integer to PDF buffer}
-var k:integer; {index to current digit ($0\le k\le23$); we assume that $|n|<10^{23}$}
-m:integer; {used to negate |n| in possibly dangerous cases}
-begin
- k:=0;
- if n<0 then
- begin pdf_out("-");
- if n>-100000000 then negate(n)
- else begin m:=-1-n; n:=m div 10; m:=(m mod 10)+1; k:=1;
- if m<10 then dig[0]:=m
- else begin dig[0]:=0; incr(n);
- end;
- end;
- end;
- repeat dig[k]:=n mod 10; n:=n div 10; incr(k);
- until n=0;
- pdf_room(k);
- while k>0 do begin
- decr(k);
- pdf_quick_out("0"+dig[k]);
- end;
-end;
-
-procedure pdf_print_two(n:integer); {prints two least significant digits in
-decimal form to PDF buffer}
-begin n:=abs(n) mod 100; pdf_out("0"+(n div 10));
-pdf_out("0"+(n mod 10));
-end;
-
-function tokens_to_string(p: pointer): str_number; {return a string from tokens
-list}
-begin
- if selector = new_string then
- pdf_error("tokens", "tokens_to_string() called while selector = new_string");
- old_setting:=selector; selector:=new_string;
- show_token_list(link(p),null,pool_size-pool_ptr);
- selector:=old_setting;
- last_tokens_string := make_string;
- tokens_to_string := last_tokens_string;
-end;
-
-
-@ To print |scaled| value to PDF output we need some subroutines to ensure
-accurary.
-
-@d max_integer == @"7FFFFFFF {$2^{31}-1$}
-@d call_func(#) == begin if # <> 0 then do_nothing end
-
-@<Glob...@>=
-@!one_bp: scaled; {scaled value corresponds to 1bp}
-@!one_hundred_bp: scaled; {scaled value corresponds to 100bp}
-@!one_hundred_inch: scaled; {scaled value corresponds to 100in}
-@!ten_pow: array[0..9] of integer; {$10^0..10^9$}
-@!scaled_out: integer; {amount of |scaled| that was taken out in
-|divide_scaled|}
-@!init_pdf_output: boolean;
-
-@ @<Set init...@>=
-one_bp := 65782; {65781.76}
-one_hundred_bp := 6578176;
-one_hundred_inch := 473628672;
-ten_pow[0] := 1;
-for i := 1 to 9 do
- ten_pow[i] := 10*ten_pow[i - 1];
-init_pdf_output := false;
-
-
-@ The following function divides |s| by |m|. |dd| is number of decimal digits.
-
-@<Declare procedures that need to be declared forward for pdftex@>=
-function divide_scaled(s, m: scaled; dd: integer): scaled;
-var q, r: scaled;
- sign, i: integer;
-begin
- sign := 1;
- if s < 0 then begin
- sign := -sign;
- s := -s;
- end;
- if m < 0 then begin
- sign := -sign;
- m := -m;
- end;
- if m = 0 then
- pdf_error("arithmetic", "divided by zero")
- else if m >= (max_integer div 10) then
- pdf_error("arithmetic", "number too big");
- q := s div m;
- r := s mod m;
- for i := 1 to dd do begin
- q := 10*q + (10*r) div m;
- r := (10*r) mod m;
- end;
- if 2*r >= m then begin
- incr(q);
- r := r - m;
- end;
- scaled_out := sign*(s - (r div ten_pow[dd]));
- divide_scaled := sign*q;
-end;
-
-function round_xn_over_d(@!x:scaled; @!n,@!d:integer):scaled;
-var positive:boolean; {was |x>=0|?}
-@!t,@!u,@!v:nonnegative_integer; {intermediate quantities}
-begin if x>=0 then positive:=true
-else begin negate(x); positive:=false;
- end;
-t:=(x mod @'100000)*n;
-u:=(x div @'100000)*n+(t div @'100000);
-v:=(u mod d)*@'100000 + (t mod @'100000);
-if u div d>=@'100000 then arith_error:=true
-else u:=@'100000*(u div d) + (v div d);
-v := v mod d;
-if 2*v >= d then
- incr(u);
-if positive then
- round_xn_over_d := u
-else
- round_xn_over_d := -u;
-end;
-
-
-@ Next subroutines are needed for controling spacing in PDF page description.
-The procedure |adv_char_width| advances |pdf_h| by the amount |w|, which is
-the character width. We cannot simply add |w| to |pdf_h|, but must
-calculate the amount corresponding to |w| in the PDF output. For PK fonts
-things are more complicated, as we have to deal with scaling bitmaps as well.
-
-@p
-procedure adv_char_width(f: internal_font_number; w: scaled); {update |pdf_h|
-by character width |w| from font |f|}
+@y
+function get_charwidth(f: internal_font_number; c: eight_bits): scaled;
begin
- if hasfmentry(f) then begin
- call_func(divide_scaled(w, pdf_font_size[f], 3));
- pdf_h := pdf_h + scaled_out;
- end
+ if is_valid_char(c) then
+ get_charwidth := char_width(f)(orig_char_info(f)(c))
else
- pdf_h := pdf_h + get_pk_char_width(f, w);
-end;
-
-procedure pdf_print_real(m, d: integer); {print $m/10^d$ as real}
-var n: integer;
-begin
- if m < 0 then begin
- pdf_out("-");
- m := -m;
- end;
- n := ten_pow[d];
- pdf_print_int(m div n);
- m := m mod n;
- if m > 0 then begin
- pdf_out(".");
- n := n div 10;
- while m < n do begin
- pdf_out("0");
- n := n div 10;
- end;
- while m mod 10 = 0 do
- m := m div 10;
- pdf_print_int(m);
- end;
-end;
-
-procedure pdf_print_bp(s: scaled); {print scaled as |bp|}
-begin
- pdf_print_real(divide_scaled(s, one_hundred_bp, fixed_decimal_digits + 2),
- fixed_decimal_digits);
-end;
-
-procedure pdf_print_mag_bp(s: scaled); {take |mag| into account}
-begin
- prepare_mag;
- if mag <> 1000 then
- s := round_xn_over_d(s, mag, 1000);
- pdf_print_bp(s);
-end;
-
-@* \[32c] PDF page description.
-
-@d pdf_x(#) == ((#) - pdf_origin_h) {convert $x$-coordinate from \.{DVI} to
-PDF}
-@d pdf_y(#) == (pdf_origin_v - (#)) {convert $y$-coordinate from \.{DVI} to
-PDF}
-
-@<Glob...@>=
-@!pdf_f: internal_font_number; {the current font in PDF output page}
-@!pdf_h: scaled; {current horizontal coordinate in PDF output page}
-@!pdf_v: scaled; {current vertical coordinate in PDF output page}
-@!pdf_last_h: scaled; {last horizontal coordinate in PDF output page}
-@!pdf_last_v: scaled; {last vertical coordinate in PDF output page}
-@!pdf_origin_h: scaled; {current horizontal origin in PDF output page}
-@!pdf_origin_v: scaled; {current vertical origin in PDF output page}
-@!pdf_first_space_corr: integer; {amount of first word spacing while drawing a string;
-for some reason it is not taken into account of the length of the string, so we
-have to save it in order to adjust spacing when string drawing is finished}
-@!pdf_doing_string: boolean; {we are writing string to PDF file?}
-@!pdf_doing_text: boolean; {we are writing text section to PDF file?}
-@!pdf_font_changed: boolean; {current font has been changed?}
-@!min_bp_val: scaled;
-@!fixed_pk_resolution: integer;
-@!fixed_decimal_digits: integer;
-@!pk_scale_factor: integer;
-@!pdf_output_option: integer;
-@!pdf_output_value: integer;
-
-@ Following procedures implement low-level subroutines to convert \TeX{}
-internal structures to PDF page description.
-
-@p procedure pdf_set_origin; {set the origin to |cur_h|, |cur_v|}
-begin
- if (abs(cur_h - pdf_origin_h) >= min_bp_val) or
- (abs(cur_v - pdf_origin_v) >= min_bp_val) then begin
- pdf_print("1 0 0 1 ");
- pdf_print_bp(cur_h - pdf_origin_h);
- pdf_origin_h := pdf_origin_h + scaled_out;
- pdf_out(" ");
- pdf_print_bp(pdf_origin_v - cur_v);
- pdf_origin_v := pdf_origin_v - scaled_out;
- pdf_print_ln(" cm");
- end;
- pdf_h := pdf_origin_h;
- pdf_last_h := pdf_origin_h;
- pdf_v := pdf_origin_v;
- pdf_last_v := pdf_origin_v;
-end;
-
-procedure pdf_end_string; {end the current string}
-begin
- if pdf_doing_string then begin
- pdf_print(")]TJ");
- if pdf_first_space_corr <> 0 then begin
- pdf_h := pdf_h - pdf_first_space_corr;
- pdf_first_space_corr := 0;
- end;
- pdf_doing_string := false;
- end;
-end;
-
-procedure pdf_moveto(v, v_out: scaled); {set the next starting point to |cur_h|, |cur_v|}
-begin
- pdf_out(" ");
- pdf_print_bp(cur_h - pdf_last_h);
- pdf_h := pdf_last_h + scaled_out;
- pdf_out(" ");
- pdf_print_real(v, fixed_decimal_digits);
- pdf_print(" Td");
- pdf_v := pdf_last_v - v_out;
- pdf_last_h := pdf_h;
- pdf_last_v := pdf_v;
-end;
-
-procedure pdf_begin_text; forward;
-
-procedure pdf_print_font_tag(f: internal_font_number);
-begin
- if pdf_font_expand_ratio[f] = 0 then
- return;
- if pdf_font_expand_ratio[f] > 0 then
- pdf_print("+"); {minus sign will be printed by |pdf_print_int|}
- pdf_print_int(pdf_font_expand_ratio[f]);
-end;
-
-procedure pdf_set_font(f: internal_font_number);
-label found;
-var p: pointer;
- k: internal_font_number;
-begin
- if not font_used[f] then
- pdf_init_font(f);
- set_ff(f);
- k := ff;
- p := pdf_font_list;
- while p <> null do begin
- set_ff(info(p));
- if ff = k then
- goto found;
- p := link(p);
- end;
- pdf_append_list(f)(pdf_font_list); {|f| not found in |pdf_font_list|}
-found:
- pdf_begin_text;
- pdf_print("/F");
- pdf_print_int(k);
- pdf_print_font_tag(f);
- pdf_print_resname_prefix;
- pdf_out(" ");
- pdf_print_bp(font_size[f]);
- pdf_print(" Tf");
- pdf_f := f;
- pdf_font_changed := true;
-end;
-
-procedure pdf_begin_text; {begin a text section}
-var temp_cur_h, temp_cur_v: scaled;
-begin
- if not pdf_doing_text then begin
- temp_cur_h := cur_h;
- temp_cur_v := cur_v;
- cur_h := 0;
- cur_v := cur_page_height;
- pdf_set_origin;
- cur_h := temp_cur_h;
- cur_v := temp_cur_v;
- pdf_print_ln("BT");
- pdf_doing_text := true;
- pdf_f := null_font;
- pdf_first_space_corr := 0;
- pdf_doing_string := false;
- end;
-end;
-
-procedure pdf_begin_string(f: internal_font_number); {begin to draw a string}
-var b: boolean; {|b| is true only when we must adjust word spacing
-at the beginning of string}
- s, s_out, v, v_out: scaled;
-begin
- pdf_begin_text;
- if f <> pdf_f then begin
- pdf_end_string;
- pdf_set_font(f);
- end;
- b := false;
- s := divide_scaled(cur_h - pdf_h, pdf_font_size[f], 3);
- s_out := scaled_out;
- if abs(cur_v - pdf_v) >= min_bp_val then begin
- v := divide_scaled(pdf_last_v - cur_v, one_hundred_bp,
- fixed_decimal_digits + 2);
- v_out := scaled_out;
- end
- else begin
- v := 0;
- v_out := 0;
- end;
- if pdf_font_changed or (v <> 0) or (abs(s) >= @'100000) then begin
- pdf_end_string;
- pdf_moveto(v, v_out);
- pdf_font_changed := false;
- s := 0;
- s_out := 0;
- end;
- if pdf_doing_string then begin
- if s <> 0 then
- pdf_out(")");
- end
- else begin
- pdf_out("[");
- if s <> 0 then
- b := true
- else
- pdf_out("(");
- pdf_doing_string := true;
- end;
- if s <> 0 then begin
- pdf_print_int(-s);
- if b then
- pdf_first_space_corr := s_out;
- pdf_out("(");
- pdf_h := pdf_h + s_out;
- end;
-end;
-
-procedure pdf_end_text; {end a text section}
-begin
- if pdf_doing_text then begin
- pdf_end_string;
- pdf_print_nl;
- pdf_print_ln("ET");
- pdf_doing_text := false;
- end;
-end;
-
-procedure pdf_set_rule(x, y, w, h: scaled); {draw a rule}
-begin
- pdf_end_text;
- pdf_set_origin;
- if h <= one_bp then begin
- pdf_print_ln("q");
- pdf_print_ln("[]0 d");
- pdf_print_ln("0 J");
- pdf_print_bp(h); pdf_print_ln(" w");
- pdf_print("0 "); pdf_print_bp((h + 1)/2); pdf_print_ln(" m");
- pdf_print_bp(w); pdf_print(" "); pdf_print_bp((h + 1)/2);
- pdf_print_ln(" l");
- pdf_print_ln("S");
- pdf_print_ln("Q");
- end
- else if w <= one_bp then begin
- pdf_print_ln("q");
- pdf_print_ln("[]0 d");
- pdf_print_ln("0 J");
- pdf_print_bp(w); pdf_print_ln(" w");
- pdf_print_bp((w + 1)/2); pdf_print_ln(" 0 m");
- pdf_print_bp((w + 1)/2); pdf_print(" "); pdf_print_bp(h);
- pdf_print_ln(" l");
- pdf_print_ln("S");
- pdf_print_ln("Q");
- end
- else begin
- pdf_print_bp(pdf_x(x)); pdf_out(" ");
- pdf_print_bp(pdf_y(y)); pdf_out(" ");
- pdf_print_bp(w); pdf_out(" ");
- pdf_print_bp(h); pdf_print_ln(" re f");
- end;
-end;
-
-
-procedure pdf_rectangle(left, top, right, bottom: scaled); {output a
-rectangle specification to PDF file}
-begin
- prepare_mag;
- pdf_print("/Rect [");
- pdf_print_mag_bp(pdf_x(left)); pdf_out(" ");
- pdf_print_mag_bp(pdf_y(bottom)); pdf_out(" ");
- pdf_print_mag_bp(pdf_x(right)); pdf_out(" ");
- pdf_print_mag_bp(pdf_y(top));
- pdf_print_ln("]");
-end;
-
-@* \[32d] The cross-reference table.
-
-The cross-reference table |obj_tab| is an array of |obj_tab_size| of
-|tab_entry|. Each entry contains four integer fields and represents an object
-in PDF file whose object number is the index of this entry in |obj_tab|.
-Objects in |obj_tab| maybe linked into list; objects in such a linked list have
-the same type.
-
-@<Types...@>=
-@!obj_entry = record@;@/
- int0, int1, int2, int3: integer;
-end;
-
-@ The first field contains information representing identifier of this object.
-It is usally a number for most of object types, but it may be a string number
-for named destination or named thread.
-
-The second field of |obj_entry| contains link to the next
-object in |obj_tab| if this object in linked in a list.
-
-The third field holds the byte offset of the object in the output PDF file.
-Objects that have been not written yet have this field set to zero. However
-sometimes we have to use this field to store some info before the object is
-written out.
-
-The last field usually represents the pointer to some auxiliary data
-structure depending on the object type; however it may be used as a counter as
-well.
-
-@d obj_info(#) == obj_tab[#].int0 {information representing identifier of this object}
-@d obj_link(#) == obj_tab[#].int1 {link to the next entry in linked list}
-@d obj_offset(#) == obj_tab[#].int2 {byte offset of this object in PDF output file}
-@d obj_aux(#) == obj_tab[#].int3 {auxiliary pointer}
-@d is_obj_written(#) == (obj_offset(#) <> 0)
-
-@# {types of objects}
-@d obj_type_others == 0 {objects which are not linked in any list}
-@d obj_type_page == 1 {index of linked list of Page objects}
-@d obj_type_pages == 2 {index of linked list of Pages objects}
-@d obj_type_font == 3 {index of linked list of Fonts objects}
-@d obj_type_outline == 4 {index of linked list of outline objects}
-@d obj_type_dest == 5 {index of linked list of destination objects}
-@d obj_type_obj == 6 {index of linked list of raw objects}
-@d obj_type_xform == 7 {index of linked list of XObject forms}
-@d obj_type_ximage == 8 {index of linked list of XObject image}
-@d obj_type_thread == 9 {index of linked list of num article threads}
-@d head_tab_max == obj_type_thread {max index of |head_tab|}
-
-@# {max number of kids for balanced trees}
-@d pages_tree_kids_max == 6 {max number of kids of Pages tree node}
-@d name_tree_kids_max == @'100000 {max number of kids of node of name tree for
-name destinations}
-
-@# {when a whatsit node representing annotation is created, words |1..3| are
-width, height and depth of this annotation; after shipping out words |1..4|
-are rectangle specification of annotation. For whatsit node representing
-destination |pdf_left| and |pdf_top| are used for some types of destinations}
-
-@# {coordinates of destinations/threads/annotations (in whatsit node)}
-@d pdf_left(#) == mem[# + 1].sc
-@d pdf_top(#) == mem[# + 2].sc
-@d pdf_right(#) == mem[# + 3].sc
-@d pdf_bottom(#) == mem[# + 4].sc
-
-@# {dimesion of destinations/threads/annotations (in whatsit node)}
-@d pdf_width(#) == mem[# + 1].sc
-@d pdf_height(#) == mem[# + 2].sc
-@d pdf_depth(#) == mem[# + 3].sc
-
-@# {data structure for \.{\\pdfliteral}}
-@d pdf_literal_data(#) == link(#+1) {data}
-@d pdf_literal_mode(#) == info(#+1) {mode of resetting the text matrix
- while writing data to the page stream}
-@# {modes of resetting the text matrix}
-@d reset_origin == 0 {end text (ET) if needed, reset text matrix}
-@d direct_page == 1 {end text (ET) if needed, don't reset text matrix}
-@d direct_always == 2 {don't reset text matrix}
-@d scan_special == 3 {look into special text}
-
-@# {data structure for \.{\\pdfobj} and \.{\\pdfrefobj}}
-@d pdf_refobj_node_size == 2 {size of whatsit node representing the raw object}
-@d pdf_obj_objnum(#) == info(# + 1) {number of the raw object}
-@d obj_data_ptr == obj_aux {pointer to |pdf_mem|}
-@d pdfmem_obj_size == 4 {size of memory in |pdf_mem| which
- |obj_data_ptr| holds}
-@d obj_obj_data(#) == pdf_mem[obj_data_ptr(#) + 0] {object data}
-@d obj_obj_is_stream(#) == pdf_mem[obj_data_ptr(#) + 1] {will this object
- be written as a stream instead of a dictionary?}
-@d obj_obj_stream_attr(#) == pdf_mem[obj_data_ptr(#) + 2] {additional
- object attributes for streams}
-@d obj_obj_is_file(#) == pdf_mem[obj_data_ptr(#) + 3] {data should be
- read from an external file?}
-
-@# {data structure for \.{\\pdfxform} and \.{\\pdfrefxform}}
-@d pdf_refxform_node_size == 5 {size of whatsit node for xform; words 1..3 are
- form dimensions}
-@d pdf_xform_objnum(#) == info(# + 4) {object number}
-@d pdfmem_xform_size == 6 {size of memory in |pdf_mem| which
- |obj_data_ptr| holds}
-@d obj_xform_width(#) == pdf_mem[obj_data_ptr(#) + 0]
-@d obj_xform_height(#) == pdf_mem[obj_data_ptr(#) + 1]
-@d obj_xform_depth(#) == pdf_mem[obj_data_ptr(#) + 2]
-@d obj_xform_box(#) == pdf_mem[obj_data_ptr(#) + 3] {this field holds
- pointer to the corresponding box}
-@d obj_xform_attr(#) == pdf_mem[obj_data_ptr(#) + 4] {additional xform
- attributes}
-@d obj_xform_resources(#) == pdf_mem[obj_data_ptr(#) + 5] {additional xform
- Resources}
-
-@# {data structure for \.{\\pdfximage} and \.{\\pdfrefximage}}
-@d pdf_refximage_node_size == 5 {size of whatsit node for ximage; words 1..3
- are image dimensions}
-@d pdf_ximage_objnum(#) == info(# + 4) {object number}
-@d pdfmem_ximage_size == 5 {size of memory in |pdf_mem| which
- |obj_data_ptr| holds}
-@d obj_ximage_width(#) == pdf_mem[obj_data_ptr(#) + 0]
-@d obj_ximage_height(#) == pdf_mem[obj_data_ptr(#) + 1]
-@d obj_ximage_depth(#) == pdf_mem[obj_data_ptr(#) + 2]
-@d obj_ximage_attr(#) == pdf_mem[obj_data_ptr(#) + 3] {additional ximage attributes}
-@d obj_ximage_data(#) == pdf_mem[obj_data_ptr(#) + 4] {pointer to image data}
-
-@# {data structure of annotations; words 1..4 represent the coordinates of
- the annotation}
-@d obj_annot_ptr == obj_aux {pointer to corresponding whatsit node}
-@d pdf_annot_node_size == 7 {size of whatsit node representing annotation}
-@d pdf_annot_data(#) == info(# + 5) {raw data of general annotations}
-@d pdf_link_attr(#) == info(# + 5) {attributes of link annotations}
-@d pdf_link_action(#) == link(# + 5) {pointer to action structure}
-@d pdf_annot_objnum(#) == mem[# + 6].int {object number of corresponding object}
-
-@# {types of actions}
-@d pdf_action_page == 0 {Goto action}
-@d pdf_action_goto == 1 {Goto action}
-@d pdf_action_thread == 2 {Thread action}
-@d pdf_action_user == 3 {user-defined action}
-
-@# {data structure of actions}
-@d pdf_action_size == 3 {size of action structure in |mem|}
-@d pdf_action_type == type {action type}
-@d pdf_action_named_id == subtype {identifier is type of name}
-@d pdf_action_id == link {destination/thread name identifier}
-@d pdf_action_file(#) == info(# + 1) {file name for external action}
-@d pdf_action_new_window(#)== link(# + 1) {open a new window?}
-@d pdf_action_page_tokens(#) == info(# + 2) {specification of goto page action}
-@d pdf_action_user_tokens(#) == info(# + 2) {user-defined action string}
-@d pdf_action_refcount(#) == link(# + 2) {counter of references to this action}
-
-@# {data structure of outlines; it's not able to write out outline entries
-before all outline entries are defined, so memory allocated for outline
-entries can't not be deallocated and will stay in memory. For this reason we
-will store data of outline entries in |pdf_mem| instead of |mem|}
-
-@d pdfmem_outline_size == 8 {size of memory in |pdf_mem| which
-|obj_outline_ptr| points to}
-@d obj_outline_count == obj_info{count of all opened children}
-@d obj_outline_ptr == obj_aux {pointer to |pdf_mem|}
-@d obj_outline_title(#) == pdf_mem[obj_outline_ptr(#)]
-@d obj_outline_parent(#) == pdf_mem[obj_outline_ptr(#) + 1]
-@d obj_outline_prev(#) == pdf_mem[obj_outline_ptr(#) + 2]
-@d obj_outline_next(#) == pdf_mem[obj_outline_ptr(#) + 3]
-@d obj_outline_first(#) == pdf_mem[obj_outline_ptr(#) + 4]
-@d obj_outline_last(#) == pdf_mem[obj_outline_ptr(#) + 5]
-@d obj_outline_action_objnum(#) == pdf_mem[obj_outline_ptr(#) + 6] {object number of
-action}
-@d obj_outline_attr(#) == pdf_mem[obj_outline_ptr(#) + 7]
-
-@# {types of destinations}
-@d pdf_dest_xyz == 0
-@d pdf_dest_fit == 1
-@d pdf_dest_fith == 2
-@d pdf_dest_fitv == 3
-@d pdf_dest_fitb == 4
-@d pdf_dest_fitbh == 5
-@d pdf_dest_fitbv == 6
-@d pdf_dest_fitr == 7
-
-@# {data structure of destinations}
-@d obj_dest_ptr == obj_aux {pointer to |pdf_dest_node|}
-@d pdf_dest_node_size == 7 {size of whatsit node for destination;
-words |1..4| hold dest dimensions, word |6| identifier type, subtype
-and identifier of destination, word |6| the corresponding object number}
-@d pdf_dest_type(#) == type(# + 5) {type of destination}
-@d pdf_dest_named_id(#) == subtype(# + 5) {is named identifier?}
-@d pdf_dest_id(#) == link(# + 5) {destination identifier}
-@d pdf_dest_xyz_zoom(#) == info(# + 6) {zoom factor for |destxyz| destination}
-@d pdf_dest_objnum(#) == link(# + 6) {object number of corresponding
-object}
-
-@# {data structure of threads; words 1..4 represent the coordinates of the
- corners}
-@d pdf_thread_node_size == 7
-@d pdf_thread_named_id(#) == subtype(# + 5) {is a named identifier}
-@d pdf_thread_id(#) == link(# + 5) {thread identifier}
-@d pdf_thread_attr(#) == info(# + 6) {attributes of thread}
-@d obj_thread_first == obj_aux {pointer to the first bead}
-
-@# {data structure of beads}
-@d pdfmem_bead_size == 5 {size of memory in |pdf_mem| which
- |obj_bead_ptr| points to}
-@d obj_bead_ptr == obj_aux {pointer to |pdf_mem|}
-@d obj_bead_rect(#) == pdf_mem[obj_bead_ptr(#)]
-@d obj_bead_page(#) == pdf_mem[obj_bead_ptr(#) + 1]
-@d obj_bead_next(#) == pdf_mem[obj_bead_ptr(#) + 2]
-@d obj_bead_prev(#) == pdf_mem[obj_bead_ptr(#) + 3]
-@d obj_bead_attr(#) == pdf_mem[obj_bead_ptr(#) + 4]
-@d obj_bead_data == obj_bead_rect {pointer to the corresponding
-whatsit node; |obj_bead_rect| is needed only when the bead rectangle has
-been written out and after that |obj_bead_data| is not needed any more
-so we can use this field for both}
-
-@<Constants...@>=
-@!inf_obj_tab_size = 32000; {min size of the cross-reference table for PDF output}
-@!sup_obj_tab_size = 8388607; {max size of the cross-reference table for PDF output}
-@!inf_dest_names_size = 10000; {min size of the destination names table for PDF output}
-@!sup_dest_names_size = 131072; {max size of the destination names table for PDF output}
-@!pdf_objtype_max = head_tab_max;
-@!pdf_pdf_box_spec_media = 0;
-@!pdf_pdf_box_spec_crop = 1;
-@!pdf_pdf_box_spec_bleed = 2;
-@!pdf_pdf_box_spec_trim = 3;
-@!pdf_pdf_box_spec_art = 4;
-
-@ @<Glob...@>=
-@!obj_tab_size:integer;
-@!obj_tab:^obj_entry;
-@!head_tab: array[1..head_tab_max] of integer;
-@!obj_ptr: integer; {objects counter}
-@!pdf_last_pages: integer; {pointer to most recently generated pages object}
-@!pdf_last_page: integer; {pointer to most recently generated page object}
-@!pdf_last_stream: integer; {pointer to most recently generated stream}
-@!pdf_stream_length: integer; {length of most recently generated stream}
-@!pdf_stream_length_offset: integer; {file offset of the last stream length}
-@!pdf_append_list_arg: integer; {for use with |pdf_append_list|}
-@!ff: integer; {for use with |set_ff|}
-
-@ @<Set init...@>=
-obj_ptr := 0;
-for k := 1 to head_tab_max do
- head_tab[k] := 0;
-
-@ Here we implement subroutines for work with objects and related things.
-Some of them are used in former parts too, so we need to declare them
-forward.
-
-@d pdf_append_list_end(#) == # := append_ptr(#, pdf_append_list_arg); end
-@d pdf_append_list(#) == begin pdf_append_list_arg := #; pdf_append_list_end
-@d set_ff(#) == begin
- if pdf_font_num[#] < 0 then
- ff := -pdf_font_num[#]
- else
- ff := #;
-end
-
-@<Declare procedures that need to be declared forward for pdftex@>=
-procedure append_dest_name(s: str_number; n: integer);
-begin
- if pdf_dest_names_ptr = dest_names_size then
- overflow("number of destination names", dest_names_size);
- dest_names[pdf_dest_names_ptr].objname := s;
- dest_names[pdf_dest_names_ptr].objnum := n;
- incr(pdf_dest_names_ptr);
-end;
-
-procedure pdf_create_obj(t, i: integer); {create an object with type |t| and
-identifier |i|}
-label done;
-var p, q: integer;
-begin
- if obj_ptr = obj_tab_size then
- overflow("indirect objects table size", obj_tab_size);
- incr(obj_ptr);
- obj_info(obj_ptr) := i;
- obj_offset(obj_ptr) := 0;
- obj_aux(obj_ptr) := 0;
- avl_put_obj(obj_ptr, t);
- if t = obj_type_page then begin
- p := head_tab[t];
- {find the right position to insert newly created object}@/
- if (p = 0) or (obj_info(p) < i) then begin
- obj_link(obj_ptr) := p;
- head_tab[t] := obj_ptr;
- end
- else begin
- while p <> 0 do begin
- if obj_info(p) < i then
- goto done;
- q := p;
- p := obj_link(p);
- end;
-done:
- obj_link(q) := obj_ptr;
- obj_link(obj_ptr) := p;
- end;
- end
- else if t <> obj_type_others then begin
- obj_link(obj_ptr) := head_tab[t];
- head_tab[t] := obj_ptr;
- if (t = obj_type_dest) and (i < 0) then
- append_dest_name(-obj_info(obj_ptr), obj_ptr);
- end;
-end;
-
-function pdf_new_objnum: integer; {create a new object and return its number}
-begin
- pdf_create_obj(obj_type_others, 0);
- pdf_new_objnum := obj_ptr;
-end;
-
-procedure pdf_begin_obj(i: integer); {begin a PDF object}
-begin
- ensure_pdf_open;
- check_pdfminorversion;
- obj_offset(i) := pdf_offset;
- pdf_print_int(i);
- pdf_print_ln(" 0 obj");
-end;
-
-procedure pdf_end_obj;
-begin
- pdf_print_ln("endobj"); {end a PDF object}
-end;
-
-procedure pdf_begin_dict(i: integer); {begin a PDF dictionary object}
-begin
- obj_offset(i) := pdf_offset;
- pdf_print_int(i);
- pdf_print_ln(" 0 obj <<");
-end;
-
-procedure pdf_end_dict; {end a PDF object of type dictionary}
-begin
- pdf_print_ln(">> endobj");
-end;
-
-procedure pdf_new_obj(t, i: integer); {begin to a new object}
-begin
- pdf_create_obj(t, i);
- pdf_begin_obj(obj_ptr);
-end;
-
-procedure pdf_new_dict(t, i: integer); {begin a new object with type dictionary}
-begin
- pdf_create_obj(t, i);
- pdf_begin_dict(obj_ptr);
-end;
-
-function append_ptr(p: pointer; i: integer): pointer; {appends a pointer with
-info |i| to the end of linked list with head |p|}
-var q: pointer;
-begin
- append_ptr := p;
- fast_get_avail(q);
- info(q) := i;
- link(q) := null;
- if p = null then begin
- append_ptr := q;
- return;
- end;
- while link(p) <> null do
- p := link(p);
- link(p) := q;
-end;
-
-function pdf_lookup_list(p: pointer; i: integer): pointer; {looks up for pointer
-with info |i| in list |p|}
-begin
- pdf_lookup_list := null;
- while p <> null do begin
- if info(p) = i then begin
- pdf_lookup_list := p;
- return;
- end;
- p := link(p);
- end;
-end;
-
-@ @<Glob...@>=
-@!pdf_image_procset: integer; {collection of image types used in current page/form}
-@!pdf_text_procset: boolean; {mask of used ProcSet's in the current page/form}
-
-@ Subroutines to print out various PDF objects
-
-@d is_hex_char(#) == (((# >= '0') and (# <= '9')) or
- ((# >= 'A') and (# <= 'F')) or
- ((# >= 'a') and (# <= 'f')))
-
-@p procedure pdf_print_fw_int(n, w: integer); {print out an integer with
-fixed width; used for outputting cross-reference table}
-var k:integer; {$0\le k\le23$}
-begin
- k:=0;
- repeat dig[k]:=n mod 10; n:=n div 10; incr(k);
- until k = w;
- pdf_room(k);
- while k>0 do begin
- decr(k);
- pdf_quick_out("0"+dig[k]);
- end;
-end;
-
-procedure pdf_int_entry(s: str_number; v: integer); {print out an entry in
-dictionary with integer value to PDF buffer}
-begin
- pdf_out("/");
- pdf_print(s);
- pdf_out(" ");
- pdf_print_int(v);
-end;
-
-procedure pdf_int_entry_ln(s: str_number; v: integer);
-begin
- pdf_int_entry(s, v);
- pdf_print_nl;
-end;
-
-procedure pdf_indirect(s: str_number; o: integer); {print out an indirect
-entry in dictionary}
-begin
- pdf_out("/");
- pdf_print(s);
- pdf_out(" ");
- pdf_print_int(o);
- pdf_print(" 0 R");
-end;
-
-procedure pdf_indirect_ln(s: str_number; o: integer);
-begin
- pdf_indirect(s, o);
- pdf_print_nl;
-end;
-
-procedure pdf_print_str(s: str_number); {print out |s| as string in PDF
-output}
-label done;
-var i, j, k: pool_pointer;
- is_hex_string: boolean;
-begin
- i := str_start[s];
- j := i + length(s) - 1;
- if i > j then begin
- pdf_print("()"); {null string}
- return;
- end;
- if (str_pool[i] = '(') and (str_pool[j] = ')') then begin
- pdf_print(s);
- return;
- end;
- is_hex_string := false;
- if (str_pool[i] <> '<') or (str_pool[j] <> '>') or odd(length(s)) then
- goto done;
- incr(i);
- decr(j);
- while i < j do begin
- if is_hex_char(str_pool[i]) and is_hex_char(str_pool[i + 1]) then
- i := i + 2
- else
- goto done;
- end;
- is_hex_string := true;
-done:
- if is_hex_string then
- pdf_print(s)
- else begin
- pdf_out("(");
- pdf_print(s);
- pdf_out(")");
- end;
-end;
-
-procedure pdf_print_str_ln(s: str_number); {print out |s| as string in PDF
-output}
-begin
- pdf_print_str(s);
- pdf_print_nl;
-end;
-
-procedure pdf_str_entry(s, v: str_number); {print out an entry in
-dictionary with string value to PDF buffer}
-begin
- if v = 0 then
- return;
- pdf_out("/");
- pdf_print(s);
- pdf_out(" ");
- pdf_print_str(v);
-end;
-
-procedure pdf_str_entry_ln(s, v: str_number);
-begin
- if v = 0 then
- return;
- pdf_str_entry(s, v);
- pdf_print_nl;
-end;
-
-@* \[32e] Font processing.
-
-As pdfTeX should also act as a back-end driver, it needs to support virtual
-font too. Information about virtual font can be found in source of some
-\.{DVI}-related programs.
-
-Whenever we want to write out a character in a font to PDF output, we
-should check whether the used font is new font (has not been used yet),
-virtual font or real font. The array |pdf_font_type| holds flag of each used
-font. After initialization flag of each font is set to |new_font_type|.
-The first time when a character of a font is written out, pdfTeX looks for
-the corresponding virtual font. If the corresponding virtual font exists, then
-the font type is set to |virtual_font_type|; otherwise it will be set to
-|real_font_type|. |subst_font_type| indicates fonts that have been substituted
-during adjusting spacing. Such fonts are linked via the |pdf_font_elink| array.
-
-@d new_font_type = 0 {new font (has not been used yet)}
-@d virtual_font_type = 1 {virtual font}
-@d real_font_type = 2 {real font}
-@d subst_font_type = 3 {substituted font}
-@d pdf_init_font(#) == begin tmp_f := #; pdf_create_font_obj; end
-@d pdf_check_vf(#) == begin
- tmp_f := #;
- do_vf;
- if pdf_font_type[#] = virtual_font_type then
- pdf_error("font", "command cannot be used with virtual font");
-end
-
-@d pdf_check_new_font(#) ==
- if pdf_font_type[#] = new_font_type then begin
- tmp_f := #;
- do_vf;
- end
-
-@<Declare procedures that need to be declared forward...@>=
-procedure pdf_create_font_obj; forward;
-procedure do_vf; forward;
-procedure scan_pdf_ext_toks; forward;
-
-@ @<Glob...@>=
-@!pdf_font_type: ^eight_bits; {the type of font}
-@!pdf_font_attr: ^str_number; {pointer to additional attributes}
-@!tmp_f: internal_font_number; {for use with |pdf_init_font|}
-
-@ To set PDF font we need to find out fonts with the same name, because \TeX\
-can load the same font several times for various sizes. For such fonts we
-define only one font resource. The array |pdf_font_num| holds the object
-number of font resource. A negative value of an entry of |pdf_font_num|
-indicates that the corresponding font shares the font resource with the font
-whose internal number is the absolute value of the entry. For partial
-downloading we also need to hold flags indicating which characters in particular
-font are used in array |pdf_char_used|.
-
-@d pdf_print_resname_prefix ==
-if pdf_resname_prefix <> 0 then
- pdf_print(pdf_resname_prefix)
-
-@p procedure pdf_use_font(f: internal_font_number; fontnum: integer);
-begin
- call_func(divide_scaled(font_size[f], one_hundred_bp,
- fixed_decimal_digits + 2));
- pdf_font_size[f] := scaled_out;
- font_used[f] := true;
- pdf_font_num[f] := fontnum;
- if pdf_move_chars > 0 then begin
- pdf_warning(0,"Primitive \pdfmovechars is obsolete.",true);
- pdf_move_chars := 0; {warn only once}
- end;
-end;
-
-procedure pdf_create_font_obj;
-var f, k: internal_font_number;
-begin
- f := tmp_f;
- if not font_used[f] then begin
- if hasfmentry(f) then begin
- {this font is scaleable, so different sizes can share a single font object}
- k := tfm_of_fm(pdf_font_map[f]);
- if (k <> f) and str_eq_str(font_name[k], font_name[f]) then begin
- pdf_use_font(f, -k);
- return;
- end;
- end;
- pdf_create_obj(obj_type_font, f);
- pdf_use_font(f, obj_ptr);
- end;
-end;
-
-@ We need to hold information about used characters in each font for partial
-downloading.
-
-@<Types...@>=
-char_used_array = array[0..31] of eight_bits;
-char_map_array = array[0..32] of eight_bits; {move chars in range 0..32}
-fm_entry_ptr = ^integer;
-
-@ @<Glob...@>=
-@!pdf_char_used: ^char_used_array; {to mark used chars}
-@!pdf_char_map: ^char_map_array; {where to map chars 0..32}
-@!pdf_font_size: ^scaled; {used size of font in PDF file}
-@!pdf_font_num: ^integer; {mapping between internal font number in \TeX\ and
- font name defined in resources in PDF file}
-@!pdf_font_map: ^fm_entry_ptr; {pointer into AVL tree of font mappings}
-@!pdf_font_list: pointer; {list of used fonts in current page}
-@!pdf_resname_prefix: str_number; {global prefix of resources name}
-@!last_tokens_string: str_number; {the number of the most recently string
-created by |tokens_to_string|}
-
-@ @<Set init...@>=
-pdf_resname_prefix := 0;
-last_tokens_string := 0;
-
-
-@ Here we implement reading information from \.{VF} file.
-
-@d vf_max_packet_length = 10000 {max length of character packet in \.{VF} file}
-
-@#
-@d vf_error = 61 {label to go to when an error occur}
-@d do_char = 70 {label to go to typesetting a character of virtual font}
-@#
-@d long_char = 242 {\.{VF} command for general character packet}
-@d vf_id = 202 {identifies \.{VF} files}
-@d put1=133 {typeset a character}
-
-@#
-@d vf_byte == getc(vf_file) {get a byte from\.{VF} file}
-@d vf_packet(#) == vf_packet_start[vf_packet_base[#] + vf_packet_end
-@d vf_packet_end(#) == #]
-
-@#
-@d bad_vf(#) == begin vf_err_str := #; goto vf_error; end {go out \.{VF}
-processing with an error message}
-@d four_cases(#) == #,#+1,#+2,#+3
-
-@#
-@d tmp_b0 == tmp_w.qqqq.b0
-@d tmp_b1 == tmp_w.qqqq.b1
-@d tmp_b2 == tmp_w.qqqq.b2
-@d tmp_b3 == tmp_w.qqqq.b3
-@d tmp_int == tmp_w.int
-
-@#
-@d scaled3u == {convert |tmp_b1..tmp_b3| to an unsigned scaled dimension}
-(((((tmp_b3*vf_z)div@'400)+(tmp_b2*vf_z))div@'400)+(tmp_b1*vf_z))div vf_beta
-@d scaled4(#) == {convert |tmp_b0..tmp_b3| to a scaled dimension}
- #:=scaled3u;
- if tmp_b0>0 then if tmp_b0=255 then # := # - vf_alpha
-@d scaled3(#) == {convert |tmp_b1..tmp_b3| to a scaled dimension}
- #:=scaled3u; @+ if tmp_b1>127 then # := # - vf_alpha
-@d scaled2 == {convert |tmp_b2..tmp_b3| to a scaled dimension}
- if tmp_b2>127 then tmp_b1:=255 else tmp_b1:=0;
- scaled3
-@d scaled1 == {convert |tmp_b3| to a scaled dimension}
- if tmp_b3>127 then tmp_b1:=255 else tmp_b1:=0;
- tmp_b2:=tmp_b1; scaled3
-
-@<Glob...@>=
-@!vf_packet_base: ^integer; {base addresses of character packets from virtual fonts}
-@!vf_default_font: ^internal_font_number; {default font in a \.{VF} file}
-@!vf_local_font_num: ^internal_font_number; {number of local fonts in a \.{VF} file}
-@!vf_packet_length: integer; {length of the current packet}
-@!vf_file: byte_file;
-@!vf_nf: internal_font_number; {the local fonts counter}
-@!vf_e_fnts: ^integer; {external font numbers}
-@!vf_i_fnts: ^internal_font_number; {corresponding internal font numbers}
-@!tmp_w: memory_word; {accumulator}
-@!vf_z: integer; {multiplier}
-@!vf_alpha: integer; {correction for negative values}
-@!vf_beta: 1..16; {divisor}
-
-@ @<Set init...@>=
-vf_nf := 0;
-
-@ The |do_vf| procedure attempts to read the \.{VF} file for a font, and sets
-|pdf_font_type| to |real_font_type| if the \.{VF} file could not be found
-or loaded, otherwise sets |pdf_font_type| to |virtual_font_type|. At this
-time, |tmp_f| is the internal font number of the current \.{TFM} font. To
-process font definitions in virtual font we call |vf_def_font|.
-
-@p procedure vf_replace_z;
-begin
- vf_alpha:=16;
- while vf_z>=@'40000000 do begin
- vf_z:=vf_z div 2;
- vf_alpha:=vf_alpha+vf_alpha;
- end;
- vf_beta:=256 div vf_alpha;
- vf_alpha:=vf_alpha*vf_z;
-end;
-
-function vf_read(k: integer): integer; {read |k| bytes as an integer from \.{VF} file}
-var i: integer;
-begin
- i := 0;
- while k > 0 do begin
- i := i*256 + vf_byte;
- decr(k);
- end;
- vf_read := i;
-end;
-
-procedure vf_local_font_warning(f, k: internal_font_number; s: str_number);
-{print a warning message if an error ocurrs during processing local fonts in
-\.{VF} file}
-begin
- print_nl(s);
- print(" in local font ");
- print(font_name[k]);
- print(" in virtual font ");
- print(font_name[f]);
- print(".vf ignored.");
-end;
-
-function vf_def_font(f: internal_font_number): internal_font_number;
-{process a local font in \.{VF} file}
-var k: internal_font_number;
- s: str_number;
- ds, fs: scaled;
- cs: four_quarters;
- c: integer;
-begin
- cs.b0 := vf_byte; cs.b1 := vf_byte; cs.b2 := vf_byte; cs.b3 := vf_byte;
- tmp_b0 := vf_byte; tmp_b1 := vf_byte; tmp_b2 := vf_byte; tmp_b3 := vf_byte;
- scaled4(fs);
- ds := vf_read(4) div @'20;
- tmp_b0 := vf_byte;
- tmp_b1 := vf_byte;
- while tmp_b0 > 0 do begin
- decr(tmp_b0);
- if vf_byte > 0 then
- do_nothing; {skip the font path}
- end;
- str_room(tmp_b1);
- while tmp_b1 > 0 do begin
- decr(tmp_b1);
- append_char(vf_byte);
- end;
- s := make_string;
- k := tfm_lookup(s, fs);
- if k = null_font then
- k := read_font_info(null_cs, s, "", fs);
- if k <> null_font then begin
- if ((cs.b0 <> 0) or (cs.b1 <> 0) or (cs.b2 <> 0) or (cs.b3 <> 0)) and
- ((font_check[k].b0 <> 0) or (font_check[k].b1 <> 0) or
- (font_check[k].b2 <> 0) or (font_check[k].b3 <> 0)) and
- ((cs.b0 <> font_check[k].b0) or (cs.b1 <> font_check[k].b1) or
- (cs.b2 <> font_check[k].b2) or (cs.b3 <> font_check[k].b3)) then
- vf_local_font_warning(f, k, "checksum mismatch");
- if ds <> font_dsize[k] then
- vf_local_font_warning(f, k, "design size mismatch");
- end;
- if pdf_font_expand_ratio[f] <> 0 then
- set_expand_param(k, f, pdf_font_expand_ratio[f]);
- vf_def_font := k;
+ get_charwidth := 0;
end;
-procedure do_vf; {process \.{VF} file with font internal number |f|}
-label vf_error;
-var cmd, k, n: integer;
- cc, cmd_length: integer;
- tfm_width: scaled;
- vf_err_str, s: str_number;
- stack_level: vf_stack_index;
- save_vf_nf: internal_font_number;
- f: internal_font_number;
-
+function get_charheight(f: internal_font_number; c: eight_bits): scaled;
begin
- f := tmp_f;
- pdf_font_type[f] := real_font_type;
- if auto_expand_vf(f) then
- return; {auto-expanded virtual font}
- stack_level := 0;
- @<Open |vf_file|, return if not found@>;
- @<Process the preamble@>;@/
- @<Process the font definitions@>;@/
- @<Allocate memory for the new virtual font@>;@/
- while cmd <= long_char do begin@/
- @<Build a character packet@>;@/
- end;
- if cmd <> post then
- bad_vf("POST command expected");
- b_close(vf_file);
- pdf_font_type[f] := virtual_font_type;
- return;
-vf_error:
- print_nl("Error in processing VF font (");
- print(font_name[f]);
- print(".vf): ");
- print(vf_err_str);
- print(", virtual font will be ignored");
- print_ln;
- b_close(vf_file);
- update_terminal;
-end;
-
-@ @<Open |vf_file|, return if not found@>=
-pack_file_name(font_name[f], "", ".vf");
-if not vf_b_open_in(vf_file) then
- return
-
-@ @<Process the preamble@>=
-if vf_byte <> pre then
- bad_vf("PRE command expected");
-if vf_byte <> vf_id then
- bad_vf("wrong id byte");
-cmd_length := vf_byte;
-for k := 1 to cmd_length do
- tmp_int := vf_byte;
-tmp_b0 := vf_byte; tmp_b1 := vf_byte; tmp_b2 := vf_byte; tmp_b3 := vf_byte;
-if ((tmp_b0 <> 0) or (tmp_b1 <> 0) or (tmp_b2 <> 0) or (tmp_b3 <> 0)) and
- ((font_check[f].b0 <> 0) or (font_check[f].b1 <> 0) or
- (font_check[f].b2 <> 0) or (font_check[f].b3 <> 0)) and
- ((tmp_b0 <> font_check[f].b0) or (tmp_b1 <> font_check[f].b1) or
- (tmp_b2 <> font_check[f].b2) or (tmp_b3 <> font_check[f].b3)) then begin
- print_nl("checksum mismatch in font ");
- print(font_name[f]);
- print(".vf ignored");
-end;
-if vf_read(4) div @'20 <> font_dsize[f] then begin
- print_nl("design size mismatch in font ");
- print(font_name[f]);
- print(".vf ignored");
-end;
-update_terminal;
-vf_z := font_size[f];
-vf_replace_z
-
-@ @<Process the font definitions@>=
-cmd := vf_byte;
-save_vf_nf := vf_nf;
-while (cmd >= fnt_def1) and (cmd <= fnt_def1 + 3) do begin
- vf_e_fnts[vf_nf] := vf_read(cmd - fnt_def1 + 1);
- vf_i_fnts[vf_nf] := vf_def_font(f);
- incr(vf_nf);
- cmd := vf_byte;
-end;
-vf_default_font[f] := save_vf_nf;
-vf_local_font_num[f] := vf_nf - save_vf_nf;
-
-@ @<Allocate memory for the new virtual font@>=
- vf_packet_base[f] := new_vf_packet(f)
-
-@ @<Build a character packet@>=
-if cmd = long_char then begin
- vf_packet_length := vf_read(4);
- cc := vf_read(4);
- if not is_valid_char(cc) then
- bad_vf("invalid character code");
- tmp_b0 := vf_byte; tmp_b1 := vf_byte; tmp_b2 := vf_byte; tmp_b3 := vf_byte;
- scaled4(tfm_width);
-end
-else begin
- vf_packet_length := cmd;
- cc := vf_byte;
- if not is_valid_char(cc) then
- bad_vf("invalid character code");
- tmp_b1 := vf_byte; tmp_b2 := vf_byte; tmp_b3 := vf_byte;
- scaled3(tfm_width);
-end;
-if vf_packet_length < 0 then
- bad_vf("negative packet length");
-if vf_packet_length > vf_max_packet_length then
- bad_vf("packet length too long");
-if (tfm_width <> char_width(f)(char_info(f)(cc))) then begin
- print_nl("character width mismatch in font ");
- print(font_name[f]);
- print(".vf ignored");
-end;
-str_room(vf_packet_length);
-while vf_packet_length > 0 do begin
- cmd := vf_byte;
- decr(vf_packet_length);
- @<Cases of \.{DVI} commands that can appear in character packet@>;
- if cmd <> nop then
- append_char(cmd);
- vf_packet_length := vf_packet_length - cmd_length;
- while cmd_length > 0 do begin
- decr(cmd_length);
- append_char(vf_byte);
- end;
-end;
-if stack_level <> 0 then
- bad_vf("more PUSHs than POPs in character packet");
-if vf_packet_length <> 0 then
- bad_vf("invalid packet length or DVI command in packet");
-@<Store the packet being built@>;
-cmd := vf_byte
-
-@ @<Store the packet being built@>=
-s := make_string;
-storepacket(f, cc, s);
-flush_str(s)
-
-@ @<Cases of \.{DVI} commands that can appear in character packet@>=
-if (cmd >= set_char_0) and (cmd <= set_char_0 + 127) then
- cmd_length := 0
-else if ((fnt_num_0 <= cmd) and (cmd <= fnt_num_0 + 63)) or
- ((fnt1 <= cmd) and (cmd <= fnt1 + 3)) then begin
- if cmd >= fnt1 then begin
- k := vf_read(cmd - fnt1 + 1);
- vf_packet_length := vf_packet_length - (cmd - fnt1 + 1);
- end
- else
- k := cmd - fnt_num_0;
- if k >= 256 then
- bad_vf("too many local fonts");
- n := 0;
- while (n < vf_local_font_num[f]) and
- (vf_e_fnts[vf_default_font[f] + n] <> k) do
- incr(n);
- if n = vf_local_font_num[f] then
- bad_vf("undefined local font");
- if k <= 63 then
- append_char(fnt_num_0 + k)
- else begin
- append_char(fnt1);
- append_char(k);
- end;
- cmd_length := 0;
- cmd := nop;
-end
-else case cmd of
-set_rule, put_rule: cmd_length := 8;
-four_cases(set1): cmd_length := cmd - set1 + 1;
-four_cases(put1): cmd_length := cmd - put1 + 1;
-four_cases(right1): cmd_length := cmd - right1 + 1;
-four_cases(w1): cmd_length := cmd - w1 + 1;
-four_cases(x1): cmd_length := cmd - x1 + 1;
-four_cases(down1): cmd_length := cmd - down1 + 1;
-four_cases(y1): cmd_length := cmd - y1 + 1;
-four_cases(z1): cmd_length := cmd - z1 + 1;
-four_cases(xxx1): begin
- cmd_length := vf_read(cmd - xxx1 + 1);
- vf_packet_length := vf_packet_length - (cmd - xxx1 + 1);
- if cmd_length > vf_max_packet_length then
- bad_vf("packet length too long");
- if cmd_length < 0 then
- bad_vf("string of negative length");
- append_char(xxx1);
- append_char(cmd_length);
- cmd := nop; {|cmd| has been already stored above as |xxx1|}
-end;
-w0, x0, y0, z0, nop:
- cmd_length := 0;
-push, pop: begin
- cmd_length := 0;
- if cmd = push then
- if stack_level = vf_stack_size then
- overflow("virtual font stack size", vf_stack_size)
- else
- incr(stack_level)
+ if is_valid_char(c) then
+ get_charheight := char_height(f)(height_depth(orig_char_info(f)(c)))
else
- if stack_level = 0 then
- bad_vf("more POPs than PUSHs in character")
- else
- decr(stack_level);
-end;
-othercases
- bad_vf("improver DVI command");
-endcases
-
-@ The |do_vf_packet| procedure is called in order to interpret the
-character packet for a virtual character. Such a packet may contain the
-instruction to typeset a character from the same or an other virtual
-font; in such cases |do_vf_packet| calls itself recursively. The
-recursion level, i.e., the number of times this has happened, is kept
-in the global variable |vf_cur_s| and should not exceed |vf_max_recursion|.
-
-@<Constants...@>=
-@!vf_max_recursion=10; {\.{VF} files shouldn't recurse beyond this level}
-@!vf_stack_size=100; {\.{DVI} files shouldn't |push| beyond this depth}
-
-@ @<Types...@>=
-@!vf_stack_index=0..vf_stack_size; {an index into the stack}
-@!vf_stack_record=record
- stack_h, stack_v, stack_w, stack_x, stack_y, stack_z: scaled;
-end;
-
-@ @<Glob...@>=
-@!vf_cur_s: 0..vf_max_recursion; {current recursion level}
-@!vf_stack: array [vf_stack_index] of vf_stack_record;
-@!vf_stack_ptr: vf_stack_index; {pointer into |vf_stack|}
-
-@ @<Set init...@>=
-vf_cur_s := 0;
-vf_stack_ptr := 0;
-
-@ Some functions for processing character packets.
-
-@p function packet_read(k: integer): integer; {read |k| bytes as an integer from
-character packet}
-var i: integer;
-begin
- i := 0;
- while k > 0 do begin
- i := i*256 + packet_byte;
- decr(k);
- end;
- packet_read := i;
-end;
-
-function packet_scaled(k: integer): integer; {get |k| bytes from packet as a
-scaled}
-var s: scaled;
-begin
- case k of
- 1: begin
- tmp_b3 := packet_byte;
- scaled1(s);
- end;
- 2: begin
- tmp_b2 := packet_byte;
- tmp_b3 := packet_byte;
- scaled2(s);
- end;
- 3: begin
- tmp_b1 := packet_byte;
- tmp_b2 := packet_byte;
- tmp_b3 := packet_byte;
- scaled3(s);
- end;
- 4: begin
- tmp_b0 := packet_byte;
- tmp_b1 := packet_byte;
- tmp_b2 := packet_byte;
- tmp_b3 := packet_byte;
- scaled4(s);
- end;
- othercases pdf_error("vf", "invalid number size");
- endcases;
- packet_scaled := s;
+ get_charheight := 0;
end;
-procedure do_vf_packet(f: internal_font_number; c: eight_bits); {typeset the \.{DVI} commands in the
-character packet for character |c| in current font |f|}
-label do_char, continue;
-var save_packet_ptr, save_packet_length: pool_pointer;
- save_vf, k, n: internal_font_number;
- base_line, save_h, save_v: scaled;
- cmd: integer;
- char_move: boolean;
- w, x, y, z: scaled;
- s: str_number;
+function get_chardepth(f: internal_font_number; c: eight_bits): scaled;
begin
- incr(vf_cur_s);
- if vf_cur_s > vf_max_recursion then
- overflow("max level recursion of virtual fonts", vf_max_recursion);
- push_packet_state;
- start_packet(f, c);
- vf_z := font_size[f];
- vf_replace_z;
- save_vf := f;
- f := vf_i_fnts[vf_default_font[save_vf]];
- save_v := cur_v;
- save_h := cur_h;
- w := 0; x := 0; y := 0; z := 0;
- while vf_packet_length > 0 do begin
- cmd := packet_byte;
- @<Do typesetting the \.{DVI} commands in virtual character packet@>;
-continue:
- end;
- cur_h := save_h;
- cur_v := save_v;
- pop_packet_state;
- vf_z := font_size[f];
- vf_replace_z;
- decr(vf_cur_s);
-end;
-
-@ The following code typesets a character to PDF output.
-
-@d output_one_char(#)==begin
- pdf_check_new_font(f);
- if pdf_font_type[f] = virtual_font_type then
- do_vf_packet(f, #)
- else begin
- pdf_begin_string(f);
- pdf_print_char(f, #);
- adv_char_width(f, char_width(f)(char_info(f)(#)));
- end;
-end
-
-
-@<Do typesetting the \.{DVI} commands in virtual character packet@>=
-if (cmd >= set_char_0) and (cmd <= set_char_0 + 127) then begin
- if not is_valid_char(cmd) then begin
- char_warning(f, cmd);
- goto continue;
- end;
- c := cmd;
- char_move := true;
- goto do_char;
-end
-else if ((fnt_num_0 <= cmd) and (cmd <= fnt_num_0 + 63)) or (cmd = fnt1) then begin
- if cmd = fnt1 then
- k := packet_byte
- else
- k := cmd - fnt_num_0;
- n := 0;
- while (n < vf_local_font_num[save_vf]) and
- (vf_e_fnts[vf_default_font[save_vf] + n] <> k) do
- incr(n);
- if (n = vf_local_font_num[save_vf]) then
- f := null_font
+ if is_valid_char(c) then
+ get_chardepth := char_depth(f)(height_depth(orig_char_info(f)(c)))
else
- f := vf_i_fnts[vf_default_font[save_vf] + n];
-end
-else case cmd of
-push: begin
- vf_stack[vf_stack_ptr].stack_h := cur_h;
- vf_stack[vf_stack_ptr].stack_v := cur_v;
- vf_stack[vf_stack_ptr].stack_w := w;
- vf_stack[vf_stack_ptr].stack_x := x;
- vf_stack[vf_stack_ptr].stack_y := y;
- vf_stack[vf_stack_ptr].stack_z := z;
- incr(vf_stack_ptr);
-end;
-pop: begin
- decr(vf_stack_ptr);
- cur_h := vf_stack[vf_stack_ptr].stack_h;
- cur_v := vf_stack[vf_stack_ptr].stack_v;
- w := vf_stack[vf_stack_ptr].stack_w;
- x := vf_stack[vf_stack_ptr].stack_x;
- y := vf_stack[vf_stack_ptr].stack_y;
- z := vf_stack[vf_stack_ptr].stack_z;
-end;
-four_cases(set1), four_cases(put1): begin
- if (set1 <= cmd) and (cmd <= set1 + 3) then begin
- tmp_int := packet_read(cmd - set1 + 1);
- char_move := true;
- end
- else begin
- tmp_int := packet_read(cmd - put1 + 1);
- char_move := false;
- end;
- if not is_valid_char(tmp_int) then begin
- char_warning(f, tmp_int);
- goto continue;
- end;
- c := tmp_int;
- goto do_char;
-end;
-set_rule, put_rule: begin
- rule_ht := packet_scaled(4);
- rule_wd := packet_scaled(4);
- if (rule_wd > 0) and (rule_ht > 0) then begin
- pdf_set_rule(cur_h, cur_v, rule_wd, rule_ht);
- if cmd = set_rule then
- cur_h := cur_h + rule_wd;
- end;
-end;
-four_cases(right1):
- cur_h := cur_h + packet_scaled(cmd - right1 + 1);
-w0, four_cases(w1): begin
- if cmd > w0 then
- w := packet_scaled(cmd - w0);
- cur_h := cur_h + w;
-end;
-x0, four_cases(x1): begin
- if cmd > x0 then
- x := packet_scaled(cmd - x0);
- cur_h := cur_h + x;
-end;
-four_cases(down1):
- cur_v := cur_v + packet_scaled(cmd - down1 + 1);
-y0, four_cases(y1): begin
- if cmd > y0 then
- y := packet_scaled(cmd - y0);
- cur_v := cur_v + y;
-end;
-z0, four_cases(z1): begin
- if cmd > z0 then
- z := packet_scaled(cmd - z0);
- cur_v := cur_v + z;
-end;
-four_cases(xxx1): begin
- tmp_int := packet_read(cmd - xxx1 + 1);
- str_room(tmp_int);
- while tmp_int > 0 do begin
- decr(tmp_int);
- append_char(packet_byte);
- end;
- s := make_string;
- literal(s, scan_special, false);
- flush_str(s);
-end;
-othercases pdf_error("vf", "invalid DVI command");
-endcases;
-goto continue;
-do_char:
-if is_valid_char(c) then
- output_one_char(c)
-else
- char_warning(f, c);
-if char_move then
- cur_h := cur_h + char_width(f)(char_info(f)(c))
-
-@* \[32f] PDF shipping out.
-To ship out a \TeX\ box to PDF page description we need to implement
-|pdf_hlist_out|, |pdf_vlist_out| and |pdf_ship_out|, which are equivalent to
-the \TeX' original |hlist_out|, |vlist_out| and |ship_out| resp. But first we
-need to declare some procedures needed in |pdf_hlist_out| and |pdf_vlist_out|.
-
-@<Declare procedures needed in |pdf_hlist_out|, |pdf_vlist_out|@>=
-procedure pdf_out_literal(p:pointer);
-var old_setting:0..max_selector; {holds print |selector|}
- s: str_number;
-begin
- old_setting:=selector; selector:=new_string;
- show_token_list(link(pdf_literal_data(p)),null,pool_size-pool_ptr);
- selector:=old_setting;
- s := make_string;
- literal(s, pdf_literal_mode(p), false);
- flush_str(s);
-end;
-
-procedure pdf_special(p: pointer);
-var old_setting:0..max_selector; {holds print |selector|}
- s: str_number;
-begin
- old_setting:=selector; selector:=new_string;
- show_token_list(link(write_tokens(p)),null,pool_size-pool_ptr);
- selector:=old_setting;
- s := make_string;
- literal(s, scan_special, true);
- flush_str(s);
-end;
-
-procedure pdf_print_toks(p: pointer); {print tokens list |p|}
-var s: str_number;
-begin
- s := tokens_to_string(p);
- if length(s) > 0 then
- pdf_print(s);
- flush_str(s);
-end;
-
-procedure pdf_print_toks_ln(p: pointer); {print tokens list |p|}
-var s: str_number;
-begin
- s := tokens_to_string(p);
- if length(s) > 0 then begin
- pdf_print(s);
- pdf_print_nl;
- end;
- flush_str(s);
+ get_chardepth := 0;
end;
+@z
-@ Similiar to |vlist_out|, |pdf_vlist_out| needs to be declared forward
-
-@p procedure@?pdf_vlist_out; forward;
-
-@ The implementation of procedure |pdf_hlist_out| is similiar to |hlist_out|
-
-@p @t\4@>@<Declare procedures needed in |pdf_hlist_out|, |pdf_vlist_out|@>@t@>@/
-procedure pdf_hlist_out; {output an |hlist_node| box}
+@x (MLTeX) l. 17413
label reswitch, move_past, fin_rule, next_p;
-var base_line: scaled; {the baseline coordinate for this box}
-@!left_edge: scaled; {the left coordinate for this box}
-@!save_h: scaled; {what |cur_h| should pop to}
-@!this_box: pointer; {pointer to containing box}
-@!g_order: glue_ord; {applicable order of infinity for glue}
-@!g_sign: normal..shrinking; {selects type of glue}
-@!p:pointer; {current position in the hlist}
-@!leader_box:pointer; {the leader box being replicated}
-@!leader_wd:scaled; {width of leader box being replicated}
-@!lx:scaled; {extra space between leader boxes}
-@!outer_doing_leaders:boolean; {were we doing leaders?}
-@!edge:scaled; {left edge of sub-box, or right edge of leader space}
-@!running_link: pointer; {pointer to `running' link if exists}
-@!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);
-base_line:=cur_v; left_edge:=cur_h;
-running_link := null;
-@<Create link annotation for the current hbox if needed@>;
-while p<>null do
- @<Output node |p| for |pdf_hlist_out| and move to the next node,
- maintaining the condition |cur_v=base_line|@>;
-decr(cur_s);
-end;
-
-@ @<Create link annotation for the current hbox if needed@>=
-if running_link = null then begin
- if is_running(pdf_link_wd) and (pdf_link_level = cur_s) then begin
- append_link(this_box, left_edge, base_line);
- running_link := last_link;
- end;
-end
-else
- last_link := running_link
+@y
+label reswitch, move_past, fin_rule, next_p, found, continue;
+@z
-@ @<Output node |p| for |pdf_hlist_out|...@>=
-reswitch: if is_char_node(p) then
- begin
- repeat f:=font(p); c:=character(p);
- if is_valid_char(c) then
+@x (MLTeX) l. 17462
+ if is_valid_char(c) then
output_one_char(c)
else
char_warning(f, c);
cur_h:=cur_h+char_width(f)(char_info(f)(c));
- p:=link(p);
- until not is_char_node(p);
- end
-else @<Output the non-|char_node| |p| for |pdf_hlist_out|
- and move to the next node@>
-
-@ @<Output the non-|char_node| |p| for |pdf_hlist_out|...@>=
-begin case type(p) of
-hlist_node,vlist_node:@<(\pdfTeX) Output a box in an hlist@>;
-rule_node: begin rule_ht:=height(p); rule_dp:=depth(p); rule_wd:=width(p);
- goto fin_rule;
- end;
-whatsit_node: @<Output the whatsit node |p| in |pdf_hlist_out|@>;
-glue_node: @<(\pdfTeX) Move right or output leaders@>;
-kern_node,math_node:cur_h:=cur_h+width(p);
-ligature_node: @<Make node |p| look like a |char_node| and |goto reswitch|@>;
-othercases do_nothing
-endcases;@/
-goto next_p;
-fin_rule: @<(\pdfTeX) Output a rule in an hlist@>;
-move_past: cur_h:=cur_h+rule_wd;
-next_p:p:=link(p);
-end
-
-@ @<(\pdfTeX) Output a box in an hlist@>=
-if list_ptr(p)=null then cur_h:=cur_h+width(p)
-else begin
- cur_v:=base_line+shift_amount(p); {shift the box down}
- temp_ptr:=p; edge:=cur_h;
- if type(p)=vlist_node then pdf_vlist_out@+else pdf_hlist_out;
- cur_h:=edge+width(p); cur_v:=base_line;
- end
-
-@ @<(\pdfTeX) Output a rule in an hlist@>=
-if is_running(rule_ht) then rule_ht:=height(this_box);
-if is_running(rule_dp) then rule_dp:=depth(this_box);
-rule_ht:=rule_ht+rule_dp; {this is the rule thickness}
-if (rule_ht>0)and(rule_wd>0) then {we don't output empty rules}
- begin cur_v:=base_line+rule_dp;
- pdf_set_rule(cur_h, cur_v, rule_wd, rule_ht);
- cur_v:=base_line;
- end
-
-@ @<(\pdfTeX) Move right or output leaders@>=
-begin g:=glue_ptr(p); rule_wd:=width(g)-cur_g;
-if g_sign<>normal then
- begin if g_sign=stretching then
- begin if stretch_order(g)=g_order then
- begin cur_glue:=cur_glue+stretch(g);
- vet_glue(float(glue_set(this_box))*cur_glue);
-@^real multiplication@>
- cur_g:=round(glue_temp);
- end;
- end
- else if shrink_order(g)=g_order then
- begin cur_glue:=cur_glue-shrink(g);
- vet_glue(float(glue_set(this_box))*cur_glue);
- cur_g:=round(glue_temp);
- end;
- end;
-rule_wd:=rule_wd+cur_g;
-if subtype(p)>=a_leaders then
- @<(\pdfTeX) Output leaders in an hlist, |goto fin_rule| if a rule
- or to |next_p| if done@>;
-goto move_past;
-end
-
-@ @<(\pdfTeX) Output leaders in an hlist...@>=
-begin leader_box:=leader_ptr(p);
-if type(leader_box)=rule_node then
- begin rule_ht:=height(leader_box); rule_dp:=depth(leader_box);
- goto fin_rule;
- end;
-leader_wd:=width(leader_box);
-if (leader_wd>0)and(rule_wd>0) then
- begin rule_wd:=rule_wd+10; {compensate for floating-point rounding}
- edge:=cur_h+rule_wd; lx:=0;
- @<Let |cur_h| be the position of the first box, and set |leader_wd+lx|
- to the spacing between corresponding parts of boxes@>;
- while cur_h+leader_wd<=edge do
- @<(\pdfTeX) Output a leader box at |cur_h|,
- then advance |cur_h| by |leader_wd+lx|@>;
- cur_h:=edge-10; goto next_p;
- end;
-end
-
-@ @<(\pdfTeX) Output a leader box at |cur_h|, ...@>=
-begin cur_v:=base_line+shift_amount(leader_box);@/
-save_h:=cur_h; temp_ptr:=leader_box;
-outer_doing_leaders:=doing_leaders; doing_leaders:=true;
-if type(leader_box)=vlist_node then pdf_vlist_out@+else pdf_hlist_out;
-doing_leaders:=outer_doing_leaders;
-cur_v:=base_line;
-cur_h:=save_h+leader_wd+lx;
-end
-
-@ The |pdf_vlist_out| routine is similar to |pdf_hlist_out|, but a bit simpler.
-@p procedure pdf_vlist_out; {output a |pdf_vlist_node| box}
-label move_past, fin_rule, next_p;
-var left_edge: scaled; {the left coordinate for this box}
-@!top_edge: scaled; {the top coordinate for this box}
-@!save_v: scaled; {what |cur_v| should pop to}
-@!this_box: pointer; {pointer to containing box}
-@!g_order: glue_ord; {applicable order of infinity for glue}
-@!g_sign: normal..shrinking; {selects type of glue}
-@!p:pointer; {current position in the vlist}
-@!leader_box:pointer; {the leader box being replicated}
-@!leader_ht:scaled; {height of leader box being replicated}
-@!lx:scaled; {extra space between leader boxes}
-@!outer_doing_leaders:boolean; {were we doing leaders?}
-@!edge:scaled; {bottom boundary of leader space}
-@!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);
-left_edge:=cur_h; cur_v:=cur_v-height(this_box); top_edge:=cur_v;
-@<Create thread for the current vbox if needed@>;
-while p<>null do
- @<Output node |p| for |pdf_vlist_out| and move to the next node,
- maintaining the condition |cur_h=left_edge|@>;
-decr(cur_s);
-end;
-
-@ @<Create thread for the current vbox if needed@>=
-if (last_thread <> null) and is_running(pdf_thread_dp) and
- (pdf_thread_level = cur_s) then
- append_thread(this_box, left_edge, top_edge + height(this_box))
-
-@ @<Output node |p| for |pdf_vlist_out|...@>=
-begin if is_char_node(p) then confusion("pdfvlistout")
-@:this can't happen pdfvlistout}{\quad pdfvlistout@>
-else @<Output the non-|char_node| |p| for |pdf_vlist_out|@>;
-next_p:p:=link(p);
-end
-
-@ @<Output the non-|char_node| |p| for |pdf_vlist_out|@>=
-begin case type(p) of
-hlist_node,vlist_node:@<(\pdfTeX) Output a box in a vlist@>;
-rule_node: begin rule_ht:=height(p); rule_dp:=depth(p); rule_wd:=width(p);
- goto fin_rule;
- end;
-whatsit_node: @<Output the whatsit node |p| in |pdf_vlist_out|@>;
-glue_node: @<(\pdfTeX) Move down or output leaders@>;
-kern_node:cur_v:=cur_v+width(p);
-othercases do_nothing
-endcases;@/
-goto next_p;
-fin_rule: @<(\pdfTeX) Output a rule in a vlist, |goto next_p|@>;
-move_past: cur_v:=cur_v+rule_ht;
-end
-
-@ @<(\pdfTeX) Output a box in a vlist@>=
-if list_ptr(p)=null then cur_v:=cur_v+height(p)+depth(p)
-else begin cur_v:=cur_v+height(p); save_v:=cur_v;
- cur_h:=left_edge+shift_amount(p); {shift the box right}
- temp_ptr:=p;
- if type(p)=vlist_node then pdf_vlist_out@+else pdf_hlist_out;
- cur_v:=save_v+depth(p); cur_h:=left_edge;
- end
-
-@ @<(\pdfTeX) Output a rule in a vlist...@>=
-if is_running(rule_wd) then rule_wd:=width(this_box);
-rule_ht:=rule_ht+rule_dp; {this is the rule thickness}
-cur_v:=cur_v+rule_ht;
-if (rule_ht>0)and(rule_wd>0) then {we don't output empty rules}
- pdf_set_rule(cur_h, cur_v, rule_wd, rule_ht);
-goto next_p
-
-@ @<(\pdfTeX) Move down or output leaders@>=
-begin g:=glue_ptr(p); rule_ht:=width(g)-cur_g;
-if g_sign<>normal then
- begin if g_sign=stretching then
- begin if stretch_order(g)=g_order then
- begin cur_glue:=cur_glue+stretch(g);
- vet_glue(float(glue_set(this_box))*cur_glue);
-@^real multiplication@>
- cur_g:=round(glue_temp);
- end;
- end
- else if shrink_order(g)=g_order then
- begin cur_glue:=cur_glue-shrink(g);
- vet_glue(float(glue_set(this_box))*cur_glue);
- cur_g:=round(glue_temp);
- end;
- end;
-rule_ht:=rule_ht+cur_g;
-if subtype(p)>=a_leaders then
- @<(\pdfTeX) Output leaders in a vlist, |goto fin_rule| if a rule
- or to |next_p| if done@>;
-goto move_past;
-end
-
-@ @<(\pdfTeX) Output leaders in a vlist...@>=
-begin leader_box:=leader_ptr(p);
-if type(leader_box)=rule_node then
- begin rule_wd:=width(leader_box); rule_dp:=0;
- goto fin_rule;
- end;
-leader_ht:=height(leader_box)+depth(leader_box);
-if (leader_ht>0)and(rule_ht>0) then
- begin rule_ht:=rule_ht+10; {compensate for floating-point rounding}
- edge:=cur_v+rule_ht; lx:=0;
- @<Let |cur_v| be the position of the first box, and set |leader_ht+lx|
- to the spacing between corresponding parts of boxes@>;
- while cur_v+leader_ht<=edge do
- @<(\pdfTeX) Output a leader box at |cur_v|,
- then advance |cur_v| by |leader_ht+lx|@>;
- cur_v:=edge-10; goto next_p;
- end;
-end
-
-@ @<(\pdfTeX) Output a leader box at |cur_v|, ...@>=
-begin cur_h:=left_edge+shift_amount(leader_box);@/
-cur_v:=cur_v+height(leader_box); save_v:=cur_v;
-temp_ptr:=leader_box;
-outer_doing_leaders:=doing_leaders; doing_leaders:=true;
-if type(leader_box)=vlist_node then pdf_vlist_out@+else pdf_hlist_out;
-doing_leaders:=outer_doing_leaders;
-cur_h:=left_edge;
-cur_v:=save_v-height(leader_box)+leader_ht+lx;
-end
-
-@ |fix_pdfoutput| freezes |pdfoutput| when something has been written to
-the output.
-
-@p procedure fix_pdfoutput;
-begin
- if not fixed_pdfoutput_set then begin
- fixed_pdfoutput := pdf_output;
- fixed_pdfoutput_set := true;
- end
- else if fixed_pdfoutput <> pdf_output then
- pdf_error("setup",
- "\pdfoutput can only be changed before anything is written to the output");
-end;
-
-
-@ |pdf_ship_out| is used instead of |ship_out| to shipout a box to PDF
-output. If |shipping_page| is not set then the output will be a Form object,
-otherwise it will be a Page object.
-
-@p procedure pdf_ship_out(p: pointer; shipping_page: boolean); {output the box |p|}
-label done, done1;
-var i,j,k:integer; {general purpose accumulators}
-r: integer; {accumulator to copy node for pending link annotation}
-save_font_list: pointer; {to save |pdf_font_list| during flushing pending forms}
-save_obj_list: pointer; {to save |pdf_obj_list|}
-save_ximage_list: pointer; {to save |pdf_ximage_list|}
-save_xform_list: pointer; {to save |pdf_xform_list|}
-save_image_procset: integer; {to save |pdf_image_procset|}
-save_text_procset: integer; {to save |pdf_text_procset|}
-pdf_last_resources: integer; {pointer to most recently generated Resources object}
-s:str_number;
-old_setting:0..max_selector; {saved |selector| setting}
-begin if tracing_output>0 then
- begin print_nl(""); print_ln;
- print("Completed box being shipped out");
-@.Completed box...@>
- end;
-if not init_pdf_output then begin
- @<Initialize variables for \.{PDF} output@>;
- init_pdf_output := true;
-end;
-is_shipping_page := shipping_page;
-if shipping_page then begin
- if term_offset>max_print_line-9 then print_ln
- else if (term_offset>0)or(file_offset>0) then print_char(" ");
- print_char("["); j:=9;
- while (count(j)=0)and(j>0) do decr(j);
- for k:=0 to j do
- begin print_int(count(k));
- if k<j then print_char(".");
- end;
- update_terminal;
-end;
-if tracing_output>0 then
- begin if shipping_page then print_char("]");
- begin_diagnostic; show_box(p); end_diagnostic(true);
- end;
-@<(\pdfTeX) Ship box |p| out@>;
-if (tracing_output<=0) and shipping_page then print_char("]");
-dead_cycles:=0;
-update_terminal; {progress report}
-@<Flush the box from memory, showing statistics if requested@>;
-end;
-
-@ @<(\pdfTeX) Ship box |p| out@>=
-@<Update the values of |max_h| and |max_v|; but if the page is too large,
- |goto done|@>;
-@<Initialize variables as |pdf_ship_out| begins@>;
-if type(p)=vlist_node then pdf_vlist_out@+else pdf_hlist_out;
-if shipping_page then
- incr(total_pages);
-cur_s:=-1;
-@<Finish shipping@>;
-done:
-
-@ @<Initialize variables as |pdf_ship_out| begins@>=
-fix_pdfoutput;
-temp_ptr:=p;
-prepare_mag;
-pdf_last_resources := pdf_new_objnum;
-@<Reset resources lists@>;
-if not shipping_page then begin
- pdf_xform_width := width(p);
- pdf_xform_height := height(p);
- pdf_xform_depth := depth(p);
- pdf_begin_dict(pdf_cur_form);
- pdf_last_stream := pdf_cur_form;
- cur_v := height(p);
- cur_h := 0;
- pdf_origin_h := 0;
- pdf_origin_v := pdf_xform_height + pdf_xform_depth;
-end
-else begin
- @<Calculate page dimensions and margins@>;
- pdf_last_page := get_obj(obj_type_page, total_pages + 1, 0);
- obj_aux(pdf_last_page) := 1; {mark that this page has beed created}
- pdf_new_dict(obj_type_others, 0);
- pdf_last_stream := obj_ptr;
- cur_h := cur_h_offset;
- cur_v := height(p) + cur_v_offset;
- pdf_origin_h := 0;
- pdf_origin_v := cur_page_height;
- @<Reset PDF mark lists@>;
-end;
-if not shipping_page then begin
- @<Write out Form stream header@>;
-end;
-@<Start stream of page/form contents@>
-
-@ @<Reset resources lists@>=
-pdf_font_list := null;
-pdf_obj_list := null;
-pdf_xform_list := null;
-pdf_ximage_list := null;
-pdf_text_procset := false;
-pdf_image_procset := 0
-
-@ @<Reset PDF mark lists@>=
-pdf_annot_list := null;
-pdf_link_list := null;
-pdf_dest_list := null;
-pdf_bead_list := null;
-last_link := null;
-last_thread := null
-
-@ @<Calculate page dimensions and margins@>=
-cur_h_offset := pdf_h_origin + h_offset;
-cur_v_offset := pdf_v_origin + v_offset;
-if pdf_page_width <> 0 then
- cur_page_width := pdf_page_width
-else
- cur_page_width := width(p) + 2*cur_h_offset;
-if pdf_page_height <> 0 then
- cur_page_height := pdf_page_height
-else
- cur_page_height := height(p) + depth(p) + 2*cur_v_offset
-
-@ Here we write out the header for Form.
-
-@<Write out Form stream header@>=
-pdf_print_ln("/Type /XObject");
-pdf_print_ln("/Subtype /Form");
-if obj_xform_attr(pdf_cur_form) <> null then begin
- pdf_print_toks_ln(obj_xform_attr(pdf_cur_form));
- delete_toks(obj_xform_attr(pdf_cur_form));
-end;
-pdf_print("/BBox [");
-pdf_print("0 0 ");
-pdf_print_bp(pdf_xform_width); pdf_out(" ");
-pdf_print_bp(pdf_xform_height + pdf_xform_depth); pdf_print_ln("]");
-pdf_print_ln("/FormType 1");
-pdf_print_ln("/Matrix [1 0 0 1 0 0]");
-pdf_indirect_ln("Resources", pdf_last_resources)
-
-@ @<Start stream of page/form contents@>=
-pdf_begin_stream;
-if shipping_page then begin
- @<Adjust transformation matrix for the magnification ratio@>;
-end
-
-@ @<Adjust transformation matrix for the magnification ratio@>=
-prepare_mag;
-if mag <> 1000 then begin
- pdf_print_real(mag, 3);
- pdf_print(" 0 0 ");
- pdf_print_real(mag, 3);
- pdf_print_ln(" 0 0 cm");
-end
-
-@ @<Finish shipping@>=
-@<Finish stream of page/form contents@>;
-if shipping_page then begin
- @<Write out page object@>;
-end;
-@<Flush out pending raw objects@>;
-@<Flush out pending forms@>;
-@<Flush out pending images@>;
-if shipping_page then begin
- @<Flush out pending PDF marks@>;
-end;
-@<Write out resources dictionary@>;
-@<Flush resources lists@>;
-if shipping_page then begin
- @<Flush PDF mark lists@>;
-end
-
-@ @<Finish stream of page/form contents@>=
-pdf_end_text;
-pdf_end_stream
-
-@ @<Write out resources dictionary@>=
-pdf_begin_dict(pdf_last_resources);
-@<Print additional resources@>;
-@<Generate font resources@>;
-@<Generate XObject resources@>;
-@<Generate ProcSet@>;
-pdf_end_dict
-
-@ @<Print additional resources@>=
-if shipping_page then begin
- if pdf_page_resources <> null then
- pdf_print_toks_ln(pdf_page_resources);
-end
-else begin
- if obj_xform_resources(pdf_cur_form) <> null then begin
- pdf_print_toks_ln(obj_xform_resources(pdf_cur_form));
- delete_toks(obj_xform_resources(pdf_cur_form));
- end;
-end
-
-@ In the end of shipping out a page we reset all the lists holding objects
-have been created during the page shipping.
-
-@d delete_toks(#) == begin delete_token_ref(#); # := null; end
-
-@<Flush resources lists@>=
-flush_list(pdf_font_list);
-flush_list(pdf_obj_list);
-flush_list(pdf_xform_list);
-flush_list(pdf_ximage_list)
-
-@ @<Flush PDF mark lists@>=
-flush_list(pdf_annot_list);
-flush_list(pdf_link_list);
-flush_list(pdf_dest_list);
-flush_list(pdf_bead_list)
-
-@ @<Generate font resources@>=
-if pdf_font_list <> null then begin
- pdf_print("/Font << ");
- k := pdf_font_list;
- while k <> null do begin
- pdf_print("/F");
- set_ff(info(k));
- pdf_print_int(ff);
- pdf_print_font_tag(info(k));
- pdf_print_resname_prefix;
- pdf_out(" ");
- pdf_print_int(pdf_font_num[ff]);
- pdf_print(" 0 R ");
- k := link(k);
- end;
- pdf_print_ln(">>");
- pdf_text_procset := true;
-end
-
-@ @<Generate XObject resources@>=
-if (pdf_xform_list <> null) or (pdf_ximage_list <> null) then begin
- pdf_print("/XObject << ");
- k := pdf_xform_list;
- while k <> null do begin
- pdf_print("/Fm");
- pdf_print_int(obj_info(info(k)));
- pdf_print_resname_prefix;
- pdf_out(" ");
- pdf_print_int(info(k));
- pdf_print(" 0 R ");
- k := link(k);
- end;
- k := pdf_ximage_list;
- while k <> null do begin
- pdf_print("/Im");
- pdf_print_int(obj_info(info(k)));
- pdf_print_resname_prefix;
- pdf_out(" ");
- pdf_print_int(info(k));
- pdf_print(" 0 R ");
- update_image_procset(obj_ximage_data(info(k)));
- k := link(k);
- end;
- pdf_print_ln(">>");
-end
-
-@ @<Generate ProcSet@>=
-pdf_print("/ProcSet [ /PDF");
-if pdf_text_procset then
- pdf_print(" /Text");
-if check_image_b(pdf_image_procset) then
- pdf_print(" /ImageB");
-if check_image_c(pdf_image_procset) then
- pdf_print(" /ImageC");
-if check_image_i(pdf_image_procset) then
- pdf_print(" /ImageI");
-pdf_print_ln(" ]")
-
-@ @<Write out page object@>=
-pdf_begin_dict(pdf_last_page);
-pdf_print_ln("/Type /Page");
-pdf_indirect_ln("Contents", pdf_last_stream);
-pdf_indirect_ln("Resources", pdf_last_resources);
-pdf_print("/MediaBox [0 0 ");
-pdf_print_mag_bp(cur_page_width); pdf_out(" ");
-pdf_print_mag_bp(cur_page_height);
-pdf_print_ln("]");
-if pdf_page_attr <> null then
- pdf_print_toks_ln(pdf_page_attr);
-@<Generate parent pages object@>;
-@<Generate array of annotations or beads in page@>;
-pdf_end_dict
-
-@ @<Generate parent pages object@>=
-if total_pages mod pages_tree_kids_max = 1 then begin
- pdf_create_obj(obj_type_pages, pages_tree_kids_max);
- pdf_last_pages := obj_ptr;
-end;
-pdf_indirect_ln("Parent", pdf_last_pages)
-
-@ @<Generate array of annotations or beads in page@>=
-if (pdf_annot_list <> null) or (pdf_link_list <> null) then begin
- pdf_print("/Annots [ ");
- k := pdf_annot_list;
- while k <> null do begin
- pdf_print_int(info(k));
- pdf_print(" 0 R ");
- k := link(k);
- end;
- k := pdf_link_list;
- while k <> null do begin
- pdf_print_int(info(k));
- pdf_print(" 0 R ");
- k := link(k);
- end;
- pdf_print_ln("]");
-end;
-if pdf_bead_list <> null then begin
- k := pdf_bead_list;
- pdf_print("/B [ ");
- while k <> null do begin
- pdf_print_int(info(k));
- pdf_print(" 0 R ");
- k := link(k);
- end;
- pdf_print_ln("]");
-end
-
-@ @<Declare procedures needed in |pdf_hlist_out|, |pdf_vlist_out|@>=
-procedure pdf_write_obj(n: integer); {write a raw PDF object}
-var s: str_number;
- f: byte_file;
-begin
- s := tokens_to_string(obj_obj_data(n));
- delete_toks(obj_obj_data(n));
- if obj_obj_is_stream(n) > 0 then begin
- pdf_begin_dict(n);
- if obj_obj_stream_attr(n) <> null then begin
- pdf_print_toks_ln(obj_obj_stream_attr(n));
- delete_toks(obj_obj_stream_attr(n));
- end;
- pdf_begin_stream;
- end
- else
- pdf_begin_obj(n);
- if obj_obj_is_file(n) > 0 then begin
- cur_name := s;
- cur_area := "";
- cur_ext := "";
- pack_cur_name;
- if not tex_b_openin(f) then
- pdf_error("ext5", "cannot open file for embedding");
- print("<<");
- print(s);
- while not eof(f) do
- pdf_out(getc(f));
- print(">>");
- b_close(f);
- end
- else if obj_obj_is_stream(n) > 0 then
- pdf_print(s)
- else
- pdf_print_ln(s);
- if obj_obj_is_stream(n) > 0 then
- pdf_end_stream
- else
- pdf_end_obj;
- flush_str(s);
-end;
-
-procedure flush_whatsit_node(p: pointer; s: small_number);
-begin
- type(p) := whatsit_node;
- subtype(p) := s;
- if link(p) <> null then
- pdf_error("flush_whatsit_node", "link(p) is not null");
- flush_node_list(p);
-end;
-
-@ @<Flush out pending raw objects@>=
-if pdf_obj_list <> null then begin
- k := pdf_obj_list;
- while k <> null do begin
- if not is_obj_written(info(k)) then
- pdf_write_obj(info(k));
- k := link(k);
- end;
-end
-
-@ When flushing pending forms we need to save and restore resources lists
- (|pdf_font_list|, |pdf_obj_list|, |pdf_xform_list| and |pdf_ximage_list|),
- which are also used by page shipping.
-
-@<Flush out pending forms@>=
-if pdf_xform_list <> null then begin
- k := pdf_xform_list;
- while k <> null do begin
- if not is_obj_written(info(k)) then begin
- pdf_cur_form := info(k);
- @<Save resources lists@>;
- @<Reset resources lists@>;
- pdf_ship_out(obj_xform_box(pdf_cur_form), false);
- @<Restore resources lists@>;
- end;
- k := link(k);
- end;
-end
-
-@ @<Save resources lists@>=
-save_font_list := pdf_font_list;
-save_obj_list := pdf_obj_list;
-save_xform_list := pdf_xform_list;
-save_ximage_list := pdf_ximage_list;
-save_text_procset := pdf_text_procset;
-save_image_procset := pdf_image_procset
-
-@ @<Restore resources lists@>=
-pdf_font_list := save_font_list;
-pdf_obj_list := save_obj_list;
-pdf_xform_list := save_xform_list;
-pdf_ximage_list := save_ximage_list;
-pdf_text_procset := save_text_procset;
-pdf_image_procset := save_image_procset
-
-@ @<Declare procedures needed in |pdf_hlist_out|, |pdf_vlist_out|@>=
-procedure pdf_write_image(n: integer); {write an image}
-begin
- pdf_begin_dict(n);
- if obj_ximage_attr(n) <> null then begin
- pdf_print_toks_ln(obj_ximage_attr(n));
- delete_toks(obj_ximage_attr(n));
- end;
- write_image(obj_ximage_data(n));
- delete_image(obj_ximage_data(n));
-end;
-
-@ @<Flush out pending images@>=
-if pdf_ximage_list <> null then begin
- k := pdf_ximage_list;
- while k <> null do begin
- if not is_obj_written(info(k)) then
- pdf_write_image(info(k));
- k := link(k);
- end;
-end
-
-@ @<Flush out pending PDF marks@>=
-pdf_origin_h := 0;
-pdf_origin_v := cur_page_height;
-@<Flush out PDF annotations@>;
-@<Flush out PDF link annotations@>;
-@<Flush out PDF mark destinations@>;
-@<Flush out PDF bead rectangle specifications@>
-
-@ @<Flush out PDF annotations@>=
-if pdf_annot_list <> null then begin
- k := pdf_annot_list;
- while k <> null do begin
- i := obj_annot_ptr(info(k)); {|i| points to |pdf_annot_node|}
- pdf_begin_dict(info(k));
- pdf_print_ln("/Type /Annot");
- pdf_print_toks_ln(pdf_annot_data(i));
- pdf_rectangle(pdf_left(i), pdf_top(i), pdf_right(i), pdf_bottom(i));
- pdf_end_dict;
- k := link(k);
- end;
-end
-
-@ @<Flush out PDF link annotations@>=
-if pdf_link_list <> null then begin
- @<Write out PDF link annotations@>;
- @<Free PDF link annotations@>;
-end
-
-@ @<Write out PDF link annotations@>=
-k := pdf_link_list;
-while k <> null do begin
- i := obj_annot_ptr(info(k));
- pdf_begin_dict(info(k));
- pdf_print_ln("/Type /Annot");
- if pdf_link_attr(i) <> null then
- pdf_print_toks_ln(pdf_link_attr(i));
- pdf_rectangle(pdf_left(i), pdf_top(i), pdf_right(i), pdf_bottom(i));
- if pdf_action_type(pdf_link_action(i)) <> pdf_action_user
- then begin
- pdf_print_ln("/Subtype /Link");
- pdf_print("/A ");
- end;
- write_action(pdf_link_action(i));
- pdf_end_dict;
- k := link(k);
-end
-
-@ @<Free PDF link annotations@>=
-k := pdf_link_list;
-while k <> null do begin
- i := obj_annot_ptr(info(k));
- {nodes with |info = null| were created by |append_link| and
- must be flushed here, as they are not linked in any list}
- if info(i) = max_halfword then
- flush_whatsit_node(i, pdf_start_link_node);
- k := link(k);
-end
-
-@ @<Flush out PDF mark destinations@>=
-if pdf_dest_list <> null then begin
- k := pdf_dest_list;
- while k <> null do begin
- if is_obj_written(info(k)) then
- pdf_error("ext5",
- "destination has been already written (this shouldn't happen)")
- else begin
- i := obj_dest_ptr(info(k));
- if pdf_dest_named_id(i) > 0 then begin
- pdf_begin_dict(info(k));
- pdf_print("/D ");
- end
- else
- pdf_begin_obj(info(k));
- pdf_out("["); pdf_print_int(pdf_last_page); pdf_print(" 0 R ");
- case pdf_dest_type(i) of
- pdf_dest_xyz: begin
- pdf_print("/XYZ ");
- pdf_print_mag_bp(pdf_x(pdf_left(i))); pdf_out(" ");
- pdf_print_mag_bp(pdf_y(pdf_top(i))); pdf_out(" ");
- if pdf_dest_xyz_zoom(i) = null then
- pdf_print("null")
- else begin
- pdf_print_int(pdf_dest_xyz_zoom(i) div 1000);
- pdf_out(".");
- pdf_print_int((pdf_dest_xyz_zoom(i) mod 1000));
- end;
- end;
- pdf_dest_fit:
- pdf_print("/Fit");
- pdf_dest_fith: begin
- pdf_print("/FitH ");
- pdf_print_mag_bp(pdf_y(pdf_top(i)));
- end;
- pdf_dest_fitv: begin
- pdf_print("/FitV ");
- pdf_print_mag_bp(pdf_x(pdf_left(i)));
- end;
- pdf_dest_fitb:
- pdf_print("/FitB");
- pdf_dest_fitbh: begin
- pdf_print("/FitBH ");
- pdf_print_mag_bp(pdf_y(pdf_top(i)));
- end;
- pdf_dest_fitbv: begin
- pdf_print("/FitBV ");
- pdf_print_mag_bp(pdf_x(pdf_left(i)));
- end;
- pdf_dest_fitr: begin
- pdf_print("/FitR ");
- pdf_print_rect_spec(i);
- end;
- othercases pdf_error("ext5", "unknown dest type");
- endcases;
- pdf_print_ln("]");
- if pdf_dest_named_id(i) > 0 then
- pdf_end_dict
- else
- pdf_end_obj;
- end;
- k := link(k);
- end;
-end
-
-@ @<Declare procedures needed in |pdf_hlist_out|, |pdf_vlist_out|@>=
-procedure pdf_print_rect_spec(r: pointer); {prints a rect spec}
-begin
- pdf_print_mag_bp(pdf_x(pdf_left(r)));
- pdf_out(" ");
- pdf_print_mag_bp(pdf_y(pdf_bottom(r)));
- pdf_out(" ");
- pdf_print_mag_bp(pdf_x(pdf_right(r)));
- pdf_out(" ");
- pdf_print_mag_bp(pdf_y(pdf_top(r)));
-end;
-
-@ @<Flush out PDF bead rectangle specifications@>=
-if pdf_bead_list <> null then begin
- k := pdf_bead_list;
- while k <> null do begin
- pdf_new_obj(obj_type_others, 0);
- pdf_out("[");
- i := obj_bead_data(info(k)); {pointer to a whatsit or whatsit-like node}
- pdf_print_rect_spec(i);
- if info(i) = max_halfword then {not a whatsit node, so must be destroyed here}
- flush_whatsit_node(i, pdf_start_thread_node);
- pdf_print_ln("]");
- obj_bead_rect(info(k)) := obj_ptr; {rewrite |obj_bead_data|}
- pdf_end_obj;
- k := link(k);
- end;
-end
-
-@ In the end we must flush PDF objects that cannot be written out
-immediately after shipping out pages.
-
-@ @<Output outlines@>=
-if pdf_first_outline <> 0 then begin
- pdf_new_dict(obj_type_others, 0);
- outlines := obj_ptr;
- l := pdf_first_outline; k := 0;
- repeat
- incr(k);
- a := open_subentries(l);
- if obj_outline_count(l) > 0 then
- k := k + a;
- obj_outline_parent(l) := obj_ptr;
- l := obj_outline_next(l);
- until l = 0;
- pdf_print_ln("/Type /Outlines");
- pdf_indirect_ln("First", pdf_first_outline);
- pdf_indirect_ln("Last", pdf_last_outline);
- pdf_int_entry_ln("Count", k);
- pdf_end_dict;
- @<Output PDF outline entries@>;
-end
-else
- outlines := 0
-
-@ @<Output PDF outline entries@>=
-k := head_tab[obj_type_outline];
-while k <> 0 do begin
- if obj_outline_parent(k) = pdf_parent_outline then begin
- if obj_outline_prev(k) = 0 then
- pdf_first_outline := k;
- if obj_outline_next(k) = 0 then
- pdf_last_outline := k;
- end;
- pdf_begin_dict(k);
- pdf_indirect_ln("Title", obj_outline_title(k));
- pdf_indirect_ln("A", obj_outline_action_objnum(k));
- if obj_outline_parent(k) <> 0 then
- pdf_indirect_ln("Parent", obj_outline_parent(k));
- if obj_outline_prev(k) <> 0 then
- pdf_indirect_ln("Prev", obj_outline_prev(k));
- if obj_outline_next(k) <> 0 then
- pdf_indirect_ln("Next", obj_outline_next(k));
- if obj_outline_first(k) <> 0 then
- pdf_indirect_ln("First", obj_outline_first(k));
- if obj_outline_last(k) <> 0 then
- pdf_indirect_ln("Last", obj_outline_last(k));
- if obj_outline_count(k) <> 0 then
- pdf_int_entry_ln("Count", obj_outline_count(k));
- if obj_outline_attr(k) <> 0 then begin
- pdf_print_toks_ln(obj_outline_attr(k));
- delete_toks(obj_outline_attr(k));
- end;
- pdf_end_dict;
- k := obj_link(k);
-end
-
-@ @<Output article threads@>=
-if head_tab[obj_type_thread] <> 0 then begin
- pdf_new_obj(obj_type_others, 0);
- threads := obj_ptr;
- pdf_out("[");
- k := head_tab[obj_type_thread];
- while k <> 0 do begin
- pdf_print_int(k);
- pdf_print(" 0 R ");
- k := obj_link(k);
- end;
- remove_last_space;
- pdf_print_ln("]");
- pdf_end_obj;
- k := head_tab[obj_type_thread];
- while k <> 0 do begin
- out_thread(k);
- k := obj_link(k);
- end;
-end
-else
- threads := 0
-
-@ Now we are ready to declare our new procedure |ship_out|. It will call
-|pdf_ship_out| if the integer parameter |pdf_output| is positive; otherwise it
-will call |dvi_ship_out|, which is the \TeX\ original |ship_out|.
-
-@p procedure ship_out(p:pointer); {output the box |p|}
-begin
- fix_pdfoutput;
- if pdf_output > 0 then
- pdf_ship_out(p, true)
- else
- dvi_ship_out(p);
-end;
-
-@ @<Initialize variables for \.{PDF} output@>=
-ensure_pdf_open;
-check_pdfminorversion;
-prepare_mag;
-fixed_decimal_digits := fix_int(pdf_decimal_digits, 0, 4);
-min_bp_val :=
- divide_scaled(one_hundred_bp, ten_pow[fixed_decimal_digits + 2], 0);
-fixed_pk_resolution := fix_int(pdf_pk_resolution, 72, 2400);
-pk_scale_factor :=
- divide_scaled(72, fixed_pk_resolution, 5 + fixed_decimal_digits);
-if pdf_pk_mode <> null then begin
- kpse_init_prog('PDFTEX', fixed_pk_resolution,
- make_cstring(tokens_to_string(pdf_pk_mode)), nil);
- flush_string;
-end else
- kpse_init_prog('PDFTEX', fixed_pk_resolution, nil, nil);
-if not kpse_var_value('MKTEXPK') then
- kpse_set_program_enabled (kpse_pk_format, 1, kpse_src_cmdline);
-set_job_id(year, month, day, time, pdftex_version, pdftex_revision);
-if (pdf_unique_resname > 0) and (pdf_resname_prefix = 0) then
- pdf_resname_prefix := get_resname_prefix
-
-@ Finishing the PDF output file.
-
-The following procedures sort the table of destination names
-@p function str_less_str(s1, s2: str_number): boolean; {compare two strings}
-var j1, j2: pool_pointer;
- l, i: integer;
-begin
- j1 := str_start[s1];
- j2 := str_start[s2];
- if length(s1) < length(s2) then
- l := length(s1)
- else
- l := length(s2);
- i := 0;
- while (i < l) and (str_pool[j1 + i] = str_pool[j2 + i]) do
- incr(i);
- if ((i < l) and (str_pool[j1 + i] < str_pool[j2 + i])) or
- ((i = l) and (length(s1) < length(s2))) then
- str_less_str := true
- else
- str_less_str := false;
-end;
-
-procedure sort_dest_names(l, r: integer); {sorts |dest_names| by names}
-var i, j: integer;
- s: str_number;
- x, y: integer;
- e: dest_name_entry;
-begin
- i := l;
- j := r;
- s := dest_names[(l + r) div 2].objname;
- repeat
- while str_less_str(dest_names[i].objname, s) do
- incr(i);
- while str_less_str(s, dest_names[j].objname) do
- decr(j);
- if i <= j then begin
- e := dest_names[i];
- dest_names[i] := dest_names[j];
- dest_names[j] := e;
- incr(i);
- decr(j);
- end;
- until i > j;
- if l < j then
- sort_dest_names(l, j);
- if i < r then
- sort_dest_names(i, r);
-end;
-
-@ Now the finish of PDF output file. At this moment all Page objects
-are already written completely to PDF output file.
-
-@<Finish the PDF file@>=
-if total_pages=0 then print_nl("No pages of output.")
-@.No pages of output@>
-else begin
- pdf_flush; {to make sure that the output file name has been already
- created}
- if total_pages mod pages_tree_kids_max <> 0 then
- obj_info(pdf_last_pages) := total_pages mod pages_tree_kids_max;
- {last pages object may have less than |pages_tree_kids_max| chilrend}
- @<Check for non-existing pages@>;
- @<Reverse the linked list of Page and Pages objects@>;
- @<Check for non-existing destinations@>;
- @<Output fonts definition@>;
- @<Output pages tree@>;
- @<Output outlines@>;
- @<Output name tree@>;
- @<Output article threads@>;
- @<Output the catalog object@>;
- pdf_print_info;
- @<Output the |obj_tab|@>;
- @<Output the trailer@>;
- pdf_flush;
- print_nl("Output written on "); print_file_name(0, output_file_name, 0);
- @.Output written on x@>
- print(" ("); print_int(total_pages); print(" page");
- if total_pages<>1 then print_char("s");
- print(", "); print_int(pdf_offset); print(" bytes).");
- libpdffinish;
- b_close(pdf_file);
-end
-
-@ Destinations that have been referenced but don't exists have
-|obj_dest_ptr=null|. Leaving them undefined might cause troubles for
-PDF browsers, so we need to fix them.
-
-@p procedure pdf_fix_dest(k: integer);
-begin
- if obj_dest_ptr(k) <> null then
- return;
- pdf_warning("dest", "", false);
- if obj_info(k) < 0 then begin
- print("name{");
- print(-obj_info(k));
- print("}");
- end
- else begin
- print("num");
- print_int(obj_info(k));
- end;
- print(" has been referenced but does not exist, replaced by a fixed one");
- print_ln; print_ln;
- pdf_begin_obj(k);
- pdf_out("[");
- pdf_print_int(head_tab[obj_type_page]);
- pdf_print_ln(" 0 R /Fit]");
- pdf_end_obj;
-end;
-
-@ @<Check for non-existing destinations@>=
-k := head_tab[obj_type_dest];
-while k <> 0 do begin
- pdf_fix_dest(k);
- k := obj_link(k);
-end
-
-@ @<Check for non-existing pages@>=
-k := head_tab[obj_type_page];
-while obj_aux(k) = 0 do begin
- pdf_warning("dest", "Page ", false);
- print_int(obj_info(k));
- print(" has been referenced but does not exist!");
- print_ln; print_ln;
- k := obj_link(k);
-end;
-head_tab[obj_type_page] := k
-
-@ @<Reverse the linked list of Page and Pages objects@>=
-k := head_tab[obj_type_page];
-l := 0;
-repeat
- i := obj_link(k);
- obj_link(k) := l;
- l := k;
- k := i;
-until k = 0;
-head_tab[obj_type_page] := l;
-k := head_tab[obj_type_pages];
-l := 0;
-repeat
- i := obj_link(k);
- obj_link(k) := l;
- l := k;
- k := i;
-until k = 0;
-head_tab[obj_type_pages] := l
-
-@ @<Output fonts definition@>=
-for k := font_base + 1 to font_ptr do
- if font_used[k] and hasfmentry(k) then begin
- if pdf_font_num[k] < 0 then
- i := -pdf_font_num[k]
- else
- i := tfm_of_fm(pdf_font_map[k]);
- if i <> k then
- for j := 0 to 255 do
- if pdf_char_marked(k, j) then
- pdf_mark_char(i, j);
- end;
-k := head_tab[obj_type_font];
-while k <> 0 do begin
- f := obj_info(k);
- do_pdf_font(k, f);
- k := obj_link(k);
-end
-
-@ We will generate in each single step the parents of all Pages/Page objects in
-the previous level. These new generated Pages object will create a new level of
-Pages tree. We will repeat this until search only one Pages object. This one
-will be the Root object.
-
-@<Output pages tree@>=
-a := obj_ptr + 1; {all Pages objects whose children are not Page objects
-should have index greater than |a|}
-l := head_tab[obj_type_pages]; {|l| is the index of current Pages object which is
-being output}
-k := head_tab[obj_type_page]; {|k| is the index of current child of |l|}
-if obj_link(l) = 0 then
- is_root := true {only Pages object; total pages is not greater than
- |pages_tree_kids_max|}
-else
- is_root := false;
-b := obj_ptr + 1; {to init |c| in next step}
-repeat
- i := 0; {counter of Pages object in current level}
- c := b; {first Pages object in previous level}
- b := obj_ptr + 1; {succcesor of last created object}
- repeat
- if not is_root then begin
- if i mod pages_tree_kids_max = 0 then begin {create a new Pages object for next level}
- pdf_last_pages := pdf_new_objnum;
- obj_info(pdf_last_pages) := obj_info(l);
- end
- else
- obj_info(pdf_last_pages) := obj_info(pdf_last_pages) +
- obj_info(l);
- end;
- @<Output the current Pages object in this level@>;
- incr(i);
- if l < a then
- l := obj_link(l)
- else
- incr(l);
- until (l = 0) or (l = b);
- if l = 0 then
- l := a;
- if b = obj_ptr then
- is_root := true;
-until false;
-done:
-
-@ @<Output the current Pages object in this level@>=
-pdf_begin_dict(l);
-pdf_print_ln("/Type /Pages");
-pdf_int_entry_ln("Count", obj_info(l));
-if not is_root then
- pdf_indirect_ln("Parent", pdf_last_pages);
-pdf_print("/Kids [");
-j := 0;
-repeat
- pdf_print_int(k);
- pdf_print(" 0 R ");
- if k < a then {the next Pages/Page object must be |obj_link(k)|}
- k := obj_link(k)
- else {|k >= a|, the next Pages object is |k + 1|}
- incr(k);
- incr(j);
-until ((l < a) and (j = obj_info(l))) or
- (k = 0) or (k = c) or
- (j = pages_tree_kids_max);
-remove_last_space;
-pdf_print_ln("]");
-if k = 0 then begin
- if head_tab[obj_type_pages] <> 0 then begin {we are in Page objects list}
- k := head_tab[obj_type_pages];
- head_tab[obj_type_pages] := 0;
- end
- else {we are in Pages objects list}
- k := a;
-end;
-if is_root and (pdf_pages_attr <> null) then
- pdf_print_toks_ln(pdf_pages_attr);
-pdf_end_dict;
-if is_root then
- goto done
-
-@ The name tree is very similiar to Pages tree so its construction should be
-certain from Pages tree construction. For intermediate node |obj_info| will be
-the first name and |obj_link| will be the last name in \.{\\Limits} array.
-Note that |pdf_dest_names_ptr| will be less than |obj_ptr|, so we test if
-|k < pdf_dest_names_ptr| then |k| is index of leaf in |dest_names|; else
-|k| will be index in |obj_tab| of some intermediate node.
-
-@<Output name tree@>=
-if pdf_dest_names_ptr = 0 then begin
- dests := 0;
- goto done1;
-end;
-sort_dest_names(0, pdf_dest_names_ptr - 1);
-a := obj_ptr + 1; {first intermediate node of name tree}
-l := a; {index of node being output}
-k := 0; {index of current child of |l|; if |k < pdf_dest_names_ptr| then this is
-pointer to |dest_names| array; otherwise it is the pointer to |obj_tab|
-(object number) }
-repeat
- c := obj_ptr + 1; {first node in current level}
- repeat
- pdf_create_obj(obj_type_others, 0); {create a new node for next level}
- @<Output the current node in this level@>;
- incr(l);
- incr(i);
- until k = c;
-until false;
-done1:
-if (dests <> 0) or (pdf_names_toks <> null) then begin
- pdf_new_dict(obj_type_others, 0);
- if (dests <> 0) then
- pdf_indirect_ln("Dests", dests);
- if pdf_names_toks <> null then begin
- pdf_print_toks_ln(pdf_names_toks);
- delete_toks(pdf_names_toks);
- end;
- pdf_end_dict;
- names_tree := obj_ptr;
-end
-else
- names_tree := 0
-
-@ @<Output the current node in this level@>=
-pdf_begin_dict(l);
-j := 0;
-if k < pdf_dest_names_ptr then begin
- obj_info(l) := dest_names[k].objname;
- pdf_print("/Names [");
- repeat
- pdf_print_str(dest_names[k].objname);
- pdf_out(" ");
- pdf_print_int(dest_names[k].objnum);
- pdf_print(" 0 R ");
- incr(j);
- incr(k);
- until (j = name_tree_kids_max) or (k = pdf_dest_names_ptr);
- remove_last_space;
- pdf_print_ln("]");
- obj_link(l) := dest_names[k - 1].objname;
- if k = pdf_dest_names_ptr then
- k := a;
-end
-else begin
- obj_info(l) := obj_info(k);
- pdf_print("/Kids [");
- repeat
- pdf_print_int(k);
- pdf_print(" 0 R ");
- incr(j);
- incr(k);
- until (j = name_tree_kids_max) or (k = c);
- remove_last_space;
- pdf_print_ln("]");
- obj_link(l) := obj_link(k - 1);
-end;
-if (l > k) or (l = a) then begin
- pdf_print("/Limits [");
- pdf_print_str(obj_info(l));
- pdf_out(" ");
- pdf_print_str(obj_link(l));
- pdf_print_ln("]");
- pdf_end_dict;
-end
-else begin
- pdf_end_dict;
- dests := l;
- goto done1;
-end
-
-@ @<Output the catalog object@>=
-pdf_new_dict(obj_type_others, 0);
-root := obj_ptr;
-pdf_print_ln("/Type /Catalog");
-pdf_indirect_ln("Pages", pdf_last_pages);
-if threads <> 0 then
- pdf_indirect_ln("Threads", threads);
-if outlines <> 0 then
- pdf_indirect_ln("Outlines", outlines);
-if names_tree <> 0 then
- pdf_indirect_ln("Names", names_tree);
-if pdf_catalog_toks <> null then begin
- pdf_print_toks_ln(pdf_catalog_toks);
- delete_toks(pdf_catalog_toks);
-end;
-if pdf_catalog_openaction <> 0 then
- pdf_indirect_ln("OpenAction", pdf_catalog_openaction);
-pdf_end_dict
-
-@ If the same keys in a dictionary are given several times,
-then it is not defined which value is choosen by an application.
-Therefore the keys |/Producer| and |/Creator| are only set,
-if the token list |pdf_info_toks|, converted to a string does
-not contain these key strings.
-
-@p function substr_of_str(s, t: str_number):boolean;
-label continue,exit;
-var j, k, kk: pool_pointer; {running indices}
-begin
- k:=str_start[t];
- while (k < str_start[t+1] - length(s)) do begin
- j:=str_start[s];
- kk:=k;
- while (j < str_start[s+1]) do begin
- if str_pool[j] <> str_pool[kk] then
- goto continue;
- incr(j);
- incr(kk);
- end;
- substr_of_str:=true;
- return;
- continue: incr(k);
- end;
- substr_of_str:=false;
-end;
-
-procedure pdf_print_info; {print info object}
-var s: str_number;
- creator_given, producer_given, creationdate_given: boolean;
-begin
- pdf_new_dict(obj_type_others, 0);
- creator_given:=false;
- producer_given:=false;
- creationdate_given:=false;
- if pdf_info_toks <> null then begin
- s:=tokens_to_string(pdf_info_toks);
- creator_given:=substr_of_str("/Creator", s);
- producer_given:=substr_of_str("/Producer", s);
- creationdate_given:=substr_of_str("/CreationDate", s);
- end;
- if not producer_given then begin
- @<Print the Producer key@>;
- end;
- if pdf_info_toks <> null then begin
- if length(s) > 0 then begin
- pdf_print(s);
- pdf_print_nl;
- end;
- flush_str(s);
- delete_toks(pdf_info_toks);
- end;
- if not creator_given then
- pdf_str_entry_ln("Creator", "TeX");
- if not creationdate_given then begin
- @<Print the CreationDate key@>;
- end;
- pdf_str_entry_ln("PTEX.Fullbanner", pdftex_banner);
- pdf_end_dict;
-end;
-
-@ @<Print the Producer key@>=
-pdf_print("/Producer (pdfTeX-");
-pdf_print_int(pdftex_version div 100);
-pdf_out(".");
-pdf_print_int(pdftex_version mod 100);
-pdf_out(".");
-pdf_print(pdftex_revision);
-pdf_print_ln(")")
-
-@ @<Print the CreationDate key@>=
-print_creation_date;
-
-@ @<Glob...@>=
-@!pdftex_banner: str_number; {the complete banner}
-
-@ @<Output the |obj_tab|@>=
-l := 0;
-for k := 1 to obj_ptr do
- if obj_offset(k) = 0 then begin
- obj_link(l) := k;
- l := k;
- end;
-obj_link(l) := 0;
-pdf_save_offset := pdf_offset;
-pdf_print_ln("xref");
-pdf_print("0 "); pdf_print_int_ln(obj_ptr + 1);
-pdf_print_fw_int(obj_link(0), 10);
-pdf_print_ln(" 65535 f ");
-for k := 1 to obj_ptr do begin
- if obj_offset(k) = 0 then begin
- pdf_print_fw_int(obj_link(k), 10);
- pdf_print_ln(" 00000 f ");
- end
- else begin
- pdf_print_fw_int(obj_offset(k), 10);
- pdf_print_ln(" 00000 n ");
- end;
-end
-
-@ @<Output the trailer@>=
-pdf_print_ln("trailer");
-pdf_print("<< ");
-pdf_int_entry_ln("Size", obj_ptr + 1);
-pdf_indirect_ln("Root", root);
-pdf_indirect_ln("Info", obj_ptr);
-if pdf_trailer_toks <> null then begin
- pdf_print_toks_ln(pdf_trailer_toks);
- delete_toks(pdf_trailer_toks);
-end;
-print_ID(output_file_name);
-pdf_print_ln(" >>");
-pdf_print_ln("startxref");
-pdf_print_int_ln(pdf_save_offset);
-pdf_print_ln("%%EOF")
-
-@* \[33] Packaging.
-@z
-
-@x [649]
-exit: hpack:=r;
-@y
-exit: {|hpack|}
-hpack:=r;
-@z
-
-@x [651]
- kern_node,math_node: x:=x+width(p);
-@y
- kern_node: x:=x+width(p);
- math_node: x:=x+width(p);
-@z
-
-@x [888] - fixlinedimen
-append_to_vlist(just_box);
-@y
-if pdf_each_line_height <> 0 then
- height(just_box) := pdf_each_line_height;
-if pdf_each_line_depth <> 0 then
- depth(just_box) := pdf_each_line_depth;
-if (pdf_first_line_height <> 0) and (cur_line = prev_graf + 1) then
- height(just_box) := pdf_first_line_height;
-if (pdf_last_line_depth <> 0) and (cur_line + 1 = best_line) then
- depth(just_box) := pdf_last_line_depth;
-append_to_vlist(just_box);
-@z
-
-@x [889]
-adjust_tail:=adjust_head; just_box:=hpack(q,cur_width,exactly);
-@y
-adjust_tail:=adjust_head;
-just_box:=hpack(q,cur_width,exactly);
-@z
-
-@x [1088] - quitvmode
-@ A paragraph begins when horizontal-mode material occurs in vertical mode,
-or when the paragraph is explicitly started by `\.{\\indent}' or
-`\.{\\noindent}'.
-
-@<Put each...@>=
-primitive("indent",start_par,1);
-@!@:indent_}{\.{\\indent} primitive@>
-primitive("noindent",start_par,0);
-@!@:no_indent_}{\.{\\noindent} primitive@>
-@y
-@ Here is a really small patch to add a new primitive called
-\.{\\quitvmode}. In vertical modes, it is identical to \.{\\indent},
-but in horizontal and math modes it is really a no-op (as opposed to
-\.{\\indent}, which executes the |indent_in_hmode| procedure).
-
-A paragraph begins when horizontal-mode material occurs in vertical mode,
-or when the paragraph is explicitly started by `\.{\\quitvmode}',
-`\.{\\indent}' or `\.{\\noindent}'.
-
-@<Put each...@>=
-primitive("indent",start_par,1);
-@!@:indent_}{\.{\\indent} primitive@>
-primitive("noindent",start_par,0);
-@!@:no_indent_}{\.{\\noindent} primitive@>
-primitive("quitvmode",start_par,2);
-@!@:quit_vmode_}{\.{\\quitvmode} primitive@>
-@z
-
-@x [1089] - quitvmode
-start_par: if chr_code=0 then print_esc("noindent")@+ else print_esc("indent");
-@y
-start_par: if chr_code=0 then print_esc("noindent")@+ else if chr_code=1 then print_esc("indent")@+ else print_esc("quitvmode");
-@z
-
-@x [1092] - quitvmode
-hmode+start_par,mmode+start_par: indent_in_hmode;
@y
-hmode+start_par,mmode+start_par: if cur_chr<>2 then indent_in_hmode;
-@z
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-% Declare the necessary variables for finishing PDF file
-% Close PDF output if necessary
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-@x [1333]
-procedure close_files_and_terminate;
-var k:integer; {all-purpose index}
-begin @<Finish the extensions@>;
-@!stat if tracing_stats>0 then @<Output statistics about this job@>;@;@+tats@/
-wake_up_terminal; @<Finish the \.{DVI} file@>;
-@y
-procedure close_files_and_terminate;
-label done, done1;
-var a, b, c, i, j, k, l: integer; {all-purpose index}
- is_root: boolean; {|pdf_last_pages| is root of Pages tree?}
- root, outlines, threads, names_tree, dests, fixed_dest: integer;
-begin @<Finish the extensions@>;
-@!stat if tracing_stats>0 then @<Output statistics about this job@>;@;@+tats@/
-wake_up_terminal;
-if fixed_pdfoutput > 0 then begin
- if history = fatal_error_stop then
- print_err(" ==> Fatal error occurred, the output PDF file is not finished!")
- else begin
- @<Finish the PDF file@>;
- end;
-end
-else begin
- @<Finish the \.{DVI} file@>;
-end;
-@z
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-% Output statistics about the pdftex specific sizes only in PDF mode.
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-@x [1334]
- wlog_ln(' ',max_in_stack:1,'i,',max_nest_stack:1,'n,',@|
- max_param_stack:1,'p,',@|
- max_buf_stack+1:1,'b,',@|
- max_save_stack+6:1,'s stack positions out of ',@|
- stack_size:1,'i,',
- nest_size:1,'n,',
- param_size:1,'p,',
- buf_size:1,'b,',
- save_size:1,'s');
- end
-@y
- wlog_ln(' ',max_in_stack:1,'i,',max_nest_stack:1,'n,',@|
- max_param_stack:1,'p,',@|
- max_buf_stack+1:1,'b,',@|
- max_save_stack+6:1,'s stack positions out of ',@|
- stack_size:1,'i,',
- nest_size:1,'n,',
- param_size:1,'p,',
- buf_size:1,'b,',
- save_size:1,'s');
- if (pdf_output > 0) then begin
- wlog_ln('PDF statistics:');
- wlog_ln(' ',obj_ptr:1,' PDF objects out of ',obj_tab_size:1);
- wlog_ln(' ',pdf_dest_names_ptr:1,' named destinations out of ',dest_names_size:1);
- wlog_ln(' ',pdf_mem_ptr:1,' words of extra memory for PDF output out of ',pdf_mem_size:1);
+ if is_valid_char(c) then begin
+ output_one_char(c);
+ cur_h:=cur_h+char_width(f)(char_info(f)(c));
+ goto continue;
end;
- end
+ if mltex_enabled_p then
+ @<(\pdfTeX) Output a substitution, |goto continue| if not possible@>;
+continue:
@z
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-% Override pdf_output value from format file with command line option
-% and initialize other options
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@x
- while (loc<limit)and(buffer[loc]=" ") do incr(loc);
- end;
-@y
- while (loc<limit)and(buffer[loc]=" ") do incr(loc);
- end;
-if (pdf_output_option <> 0) then pdf_output := pdf_output_value;
-pdf_init_map_file('pdftex.map');
-@z
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-% PDF-speficic extensions that don't fall to any previous category
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-@x [1344]
-@d set_language_code=5 {command modifier for \.{\\setlanguage}}
-@y
-@d set_language_code=5 {command modifier for \.{\\setlanguage}}
-@d pdftex_first_extension_code = 6
-@d pdf_literal_node == pdftex_first_extension_code + 0
-@d pdf_obj_code == pdftex_first_extension_code + 1
-@d pdf_refobj_node == pdftex_first_extension_code + 2
-@d pdf_xform_code == pdftex_first_extension_code + 3
-@d pdf_refxform_node == pdftex_first_extension_code + 4
-@d pdf_ximage_code == pdftex_first_extension_code + 5
-@d pdf_refximage_node == pdftex_first_extension_code + 6
-@d pdf_annot_node == pdftex_first_extension_code + 7
-@d pdf_start_link_node == pdftex_first_extension_code + 8
-@d pdf_end_link_node == pdftex_first_extension_code + 9
-@d pdf_outline_code == pdftex_first_extension_code + 10
-@d pdf_dest_node == pdftex_first_extension_code + 11
-@d pdf_thread_node == pdftex_first_extension_code + 12
-@d pdf_start_thread_node == pdftex_first_extension_code + 13
-@d pdf_end_thread_node == pdftex_first_extension_code + 14
-@d pdf_save_pos_node == pdftex_first_extension_code + 15
-@d pdf_info_code == pdftex_first_extension_code + 16
-@d pdf_catalog_code == pdftex_first_extension_code + 17
-@d pdf_names_code == pdftex_first_extension_code + 18
-@d pdf_font_attr_code == pdftex_first_extension_code + 19
-@d pdf_include_chars_code == pdftex_first_extension_code + 20
-@d pdf_map_file_code == pdftex_first_extension_code + 21
-@d pdf_map_line_code == pdftex_first_extension_code + 22
-@d pdf_trailer_code == pdftex_first_extension_code + 23
-@d pdf_strcmp_code == pdftex_first_extension_code + 24
-@d pdf_escape_string_code == pdftex_first_extension_code + 25
-@d pdf_escape_name_code == pdftex_first_extension_code + 26
-@d reset_timer_code == pdftex_first_extension_code + 27
-@d pdftex_last_extension_code == pdftex_first_extension_code + 27
-@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("pdfliteral",extension,pdf_literal_node);@/
-@!@:pdf_literal_}{\.{\\pdfliteral} primitive@>
-primitive("pdfobj",extension,pdf_obj_code);@/
-@!@:pdf_obj_}{\.{\\pdfobj} primitive@>
-primitive("pdfrefobj",extension,pdf_refobj_node);@/
-@!@:pdf_refobj_}{\.{\\pdfrefobj} primitive@>
-primitive("pdfxform",extension,pdf_xform_code);@/
-@!@:pdf_xform_}{\.{\\pdfxform} primitive@>
-primitive("pdfrefxform",extension,pdf_refxform_node);@/
-@!@:pdf_refxform_}{\.{\\pdfrefxform} primitive@>
-primitive("pdfximage",extension,pdf_ximage_code);@/
-@!@:pdf_ximage_}{\.{\\pdfximage} primitive@>
-primitive("pdfrefximage",extension,pdf_refximage_node);@/
-@!@:pdf_refximage_}{\.{\\pdfrefximage} primitive@>
-primitive("pdfannot",extension,pdf_annot_node);@/
-@!@:pdf_annot_}{\.{\\pdfannot} primitive@>
-primitive("pdfstartlink",extension,pdf_start_link_node);@/
-@!@:pdf_start_link_}{\.{\\pdfstartlink} primitive@>
-primitive("pdfendlink",extension,pdf_end_link_node);@/
-@!@:pdf_end_link_}{\.{\\pdfendlink} primitive@>
-primitive("pdfoutline",extension,pdf_outline_code);@/
-@!@:pdf_outline_}{\.{\\pdfoutline} primitive@>
-primitive("pdfdest",extension,pdf_dest_node);@/
-@!@:pdf_dest_}{\.{\\pdfdest} primitive@>
-primitive("pdfthread",extension,pdf_thread_node);@/
-@!@:pdf_thread_}{\.{\\pdfthread} primitive@>
-primitive("pdfstartthread",extension,pdf_start_thread_node);@/
-@!@:pdf_start_thread_}{\.{\\pdfstartthread} primitive@>
-primitive("pdfendthread",extension,pdf_end_thread_node);@/
-@!@:pdf_end_thread_}{\.{\\pdfendthread} primitive@>
-primitive("pdfsavepos",extension,pdf_save_pos_node);@/
-@!@:pdf_save_pos_}{\.{\\pdfsavepos} primitive@>
-primitive("pdfinfo",extension,pdf_info_code);@/
-@!@:pdf_info_}{\.{\\pdfinfo} primitive@>
-primitive("pdfcatalog",extension,pdf_catalog_code);@/
-@!@:pdf_catalog_}{\.{\\pdfcatalog} primitive@>
-primitive("pdfnames",extension,pdf_names_code);@/
-@!@:pdf_names_}{\.{\\pdfnames} primitive@>
-primitive("pdfincludechars",extension,pdf_include_chars_code);@/
-@!@:pdf_include_chars_}{\.{\\pdfincludechars} primitive@>
-primitive("pdffontattr",extension,pdf_font_attr_code);@/
-@!@:pdf_font_attr_}{\.{\\pdffontattr} primitive@>
-primitive("pdfmapfile",extension,pdf_map_file_code);@/
-@!@:pdf_map_file_}{\.{\\pdfmapfile} primitive@>
-primitive("pdfmapline",extension,pdf_map_line_code);@/
-@!@:pdf_map_line_}{\.{\\pdfmapline} primitive@>
-primitive("pdftrailer",extension,pdf_trailer_code);@/
-@!@:pdf_trailer_}{\.{\\pdftrailer} primitive@>
-primitive("pdfstrcmp",extension,pdf_strcmp_code);@/
-@!@:pdf_strcmp_}{\.{\\pdfstrcmp} primitive@>
-primitive("pdfescapestring",extension,pdf_escape_string_code);@/
-@!@:pdf_escape_string_}{\.{\\pdfescapestring} primitive@>
-primitive("pdfescapename",extension,pdf_escape_name_code);@/
-@!@:pdf_escape_name_}{\.{\\pdfescapename} primitive@>
-primitive("pdfresettimer",extension,reset_timer_code);@/
-@!@:reset_timer_}{\.{\\pdfresettimer} primitive@>
-@z
-
-@x [1346]
- set_language_code:print_esc("setlanguage");
-@y
- set_language_code:print_esc("setlanguage");
- pdf_literal_node: print_esc("pdfliteral");
- pdf_obj_code: print_esc("pdfobj");
- pdf_refobj_node: print_esc("pdfrefobj");
- pdf_xform_code: print_esc("pdfxform");
- pdf_refxform_node: print_esc("pdfrefxform");
- pdf_ximage_code: print_esc("pdfximage");
- pdf_refximage_node: print_esc("pdfrefximage");
- pdf_annot_node: print_esc("pdfannot");
- pdf_start_link_node: print_esc("pdfstartlink");
- pdf_end_link_node: print_esc("pdfendlink");
- pdf_outline_code: print_esc("pdfoutline");
- pdf_dest_node: print_esc("pdfdest");
- pdf_thread_node: print_esc("pdfthread");
- pdf_start_thread_node: print_esc("pdfstartthread");
- pdf_end_thread_node: print_esc("pdfendthread");
- pdf_save_pos_node: print_esc("pdfsavepos");
- pdf_info_code: print_esc("pdfinfo");
- pdf_catalog_code: print_esc("pdfcatalog");
- pdf_names_code: print_esc("pdfnames");
- pdf_include_chars_code: print_esc("pdfincludechars");
- pdf_font_attr_code: print_esc("pdffontattr");
- pdf_map_file_code: print_esc("pdfmapfile");
- pdf_map_line_code: print_esc("pdfmapline");
- pdf_trailer_code: print_esc("pdftrailer");
- pdf_strcmp_code: print_esc("pdfstrcmp");
- pdf_escape_string_code: print_esc("pdfescapestring");
- pdf_escape_name_code: print_esc("pdfescapename");
- reset_timer_code: print_esc("pdfresettimer");
-@z
-
-@x [1348]
-immediate_code:@<Implement \.{\\immediate}@>;
-set_language_code:@<Implement \.{\\setlanguage}@>;
-@y
-immediate_code:@<Implement \.{\\immediate}@>;
-set_language_code:@<Implement \.{\\setlanguage}@>;
-pdf_literal_node: @<Implement \.{\\pdfliteral}@>;
-pdf_obj_code: @<Implement \.{\\pdfobj}@>;
-pdf_refobj_node: @<Implement \.{\\pdfrefobj}@>;
-pdf_xform_code: @<Implement \.{\\pdfxform}@>;
-pdf_refxform_node: @<Implement \.{\\pdfrefxform}@>;
-pdf_ximage_code: @<Implement \.{\\pdfximage}@>;
-pdf_refximage_node: @<Implement \.{\\pdfrefximage}@>;
-pdf_annot_node: @<Implement \.{\\pdfannot}@>;
-pdf_start_link_node: @<Implement \.{\\pdfstartlink}@>;
-pdf_end_link_node: @<Implement \.{\\pdfendlink}@>;
-pdf_outline_code: @<Implement \.{\\pdfoutline}@>;
-pdf_dest_node: @<Implement \.{\\pdfdest}@>;
-pdf_thread_node: @<Implement \.{\\pdfthread}@>;
-pdf_start_thread_node: @<Implement \.{\\pdfstartthread}@>;
-pdf_end_thread_node: @<Implement \.{\\pdfendthread}@>;
-pdf_save_pos_node: @<Implement \.{\\pdfsavepos}@>;
-pdf_info_code: @<Implement \.{\\pdfinfo}@>;
-pdf_catalog_code: @<Implement \.{\\pdfcatalog}@>;
-pdf_names_code: @<Implement \.{\\pdfnames}@>;
-pdf_include_chars_code: @<Implement \.{\\pdfincludechars}@>;
-pdf_font_attr_code: @<Implement \.{\\pdffontattr}@>;
-pdf_map_file_code: @<Implement \.{\\pdfmapfile}@>;
-pdf_map_line_code: @<Implement \.{\\pdfmapline}@>;
-pdf_trailer_code: @<Implement \.{\\pdftrailer}@>;
-pdf_strcmp_code: @<Implement \.{\\pdfstrcmp}@>;
-pdf_escape_string_code: @<Implement \.{\\pdfescapestring}@>;
-pdf_escape_name_code: @<Implement \.{\\pdfescapename}@>;
-reset_timer_code: @<Implement \.{\\pdfresettimer}@>;
-@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
+@ The |pdf_vlist_out| routine is similar to |pdf_hlist_out|, but a bit simpler.
@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
-
-@ The following macros are needed for further manipulation with whatsit nodes
-for \pdfTeX{} extensions (copying, destroying etc.)
-
-@d add_action_ref(#) == incr(pdf_action_refcount(#)) {increase count of
-references to this action}
-
-@d delete_action_ref(#) == {decrease count of references to this
-action; free it if there is no reference to this action}
-begin
- if pdf_action_refcount(#) = null then begin
- if pdf_action_type(#) = pdf_action_user then
- delete_token_ref(pdf_action_user_tokens(#))
- else begin
- if pdf_action_file(#) <> null then
- delete_token_ref(pdf_action_file(#));
- if pdf_action_type(#) = pdf_action_page then
- delete_token_ref(pdf_action_page_tokens(#))
- else if pdf_action_named_id(#) > 0 then
- delete_token_ref(pdf_action_id(#));
- end;
- free_node(#, pdf_action_size);
- end
- else
- decr(pdf_action_refcount(#));
-end
-
-@ We have to check whether \.{\\pdfoutput} is set for using \pdfTeX{}
- extensions.
-@<Declare procedures needed in |do_ext...@>=
-procedure check_pdfoutput(s: str_number; is_error : boolean);
-begin
- if pdf_output <= 0 then
- if is_error then
- pdf_error(s, "used while \pdfoutput is not set")
- else
- pdf_warning(s, "used while \pdfoutput is not set; ignoring it", true);
-end;
-
-procedure scan_pdf_ext_toks;
-begin
- call_func(scan_toks(false, true)); {like \.{\\special}}
-end;
-
-procedure compare_strings; {to implement \.{\\pdfstrcmp}}
-label done;
-var s1, s2: str_number;
- i1, i2, j1, j2: pool_pointer;
- result: integer;
-begin
- call_func(scan_toks(false, true));
- s1 := tokens_to_string(def_ref);
- delete_token_ref(def_ref);
- call_func(scan_toks(false, true));
- s2 := tokens_to_string(def_ref);
- delete_token_ref(def_ref);
- i1 := str_start[s1];
- j1 := str_start[s1 + 1];
- i2 := str_start[s2];
- j2 := str_start[s2 + 1];
- while (i1 < j1) and (i2 < j2) do begin
- if str_pool[i1] < str_pool[i2] then begin
- result := -1;
- goto done;
- end;
- if str_pool[i1] > str_pool[i2] then begin
- result := 1;
- goto done;
- end;
- incr(i1);
- incr(i2);
- end;
- if (i1 = j1) and (i2 = j2) then
- result := 0
- else if i1 < j1 then
- result := 1
- else
- result := -1;
-done:
- pdf_retval := result;
- flush_str(s2);
- flush_str(s1);
-end;
-
-@ @<Implement \.{\\pdfliteral}@>=
-begin
- check_pdfoutput("\pdfliteral", true);
- new_whatsit(pdf_literal_node, write_node_size);
- if scan_keyword("direct") then
- pdf_literal_mode(tail) := direct_always
- else if scan_keyword("page") then
- pdf_literal_mode(tail) := direct_page
- else
- pdf_literal_mode(tail) := reset_origin;
- scan_pdf_ext_toks;
- pdf_literal_data(tail) := def_ref;
-end
-
-@ The \.{\\pdfobj} primitive is used to create a ``raw'' object in the PDF
- output file. The object contents will be hold in memory and will be written
- out only when the object is referenced by \.{\\pdfrefobj}. When \.{\\pdfobj}
- is used with \.{\\immediate}, the object contents will be written out
- immediately. Objects referenced in the current page are appended into
- |pdf_obj_list|.
-
-@<Glob...@>=
-@!pdf_last_obj: integer;
-
-@ @<Implement \.{\\pdfobj}@>=
-begin
- check_pdfoutput("\pdfobj", true);
- if scan_keyword("reserveobjnum") then begin
- @<Scan an optional space@>;
- incr(pdf_obj_count);
- pdf_create_obj(obj_type_obj, pdf_obj_count);
- pdf_last_obj := obj_ptr;
- end
- else begin
- k := -1;
- if scan_keyword("useobjnum") then begin
- scan_int;
- k := cur_val;
- if (k <= 0) or (k > obj_ptr) or (obj_data_ptr(k) <> 0) then begin
- pdf_warning("\pdfobj", "invalid object number being ignored", true);
- pdf_retval := -1; {signal the problem}
- k := -1; {will be generated again}
- end;
- end;
- if k < 0 then begin
- incr(pdf_obj_count);
- pdf_create_obj(obj_type_obj, pdf_obj_count);
- k := obj_ptr;
- end;
- obj_data_ptr(k) := pdf_get_mem(pdfmem_obj_size);
- if scan_keyword("stream") then begin
- obj_obj_is_stream(k) := 1;
- if scan_keyword("attr") then begin
- scan_pdf_ext_toks;
- obj_obj_stream_attr(k) := def_ref;
- end
- else
- obj_obj_stream_attr(k) := null;
- end
- else
- obj_obj_is_stream(k) := 0;
- if scan_keyword("file") then
- obj_obj_is_file(k) := 1
- else
- obj_obj_is_file(k) := 0;
- scan_pdf_ext_toks;
- obj_obj_data(k) := def_ref;
- pdf_last_obj := k;
- end;
-end
-
-@ We need to check whether the referenced object exists.
-
-@<Declare procedures that need to be declared forward for pdftex@>=
-procedure pdf_check_obj(t, n: integer);
-var k: integer;
-begin
- k := head_tab[t];
- while (k <> 0) and (k <> n) do
- k := obj_link(k);
- if k = 0 then
- pdf_error("ext1", "cannot find referenced object");
-end;
-
-@ @<Implement \.{\\pdfrefobj}@>=
-begin
- check_pdfoutput("\pdfrefobj", true);
- scan_int;
- pdf_check_obj(obj_type_obj, cur_val);
- new_whatsit(pdf_refobj_node, pdf_refobj_node_size);
- pdf_obj_objnum(tail) := cur_val;
-end
-
-@ \.{\\pdfxform} and \.{\\pdfrefxform} are similiar to \.{\\pdfobj} and
- \.{\\pdfrefobj}
-
-@<Glob...@>=
-@!pdf_last_xform: integer;
-
-@ @<Implement \.{\\pdfxform}@>=
-begin
- check_pdfoutput("\pdfxform", true);
- incr(pdf_xform_count);
- pdf_create_obj(obj_type_xform, pdf_xform_count);
- k := obj_ptr;
- obj_data_ptr(k) := pdf_get_mem(pdfmem_xform_size);
- if scan_keyword("attr") then begin
- scan_pdf_ext_toks;
- obj_xform_attr(k) := def_ref;
- end
- else
- obj_xform_attr(k) := null;
- if scan_keyword("resources") then begin
- scan_pdf_ext_toks;
- obj_xform_resources(k) := def_ref;
- end
- else
- obj_xform_resources(k) := null;
- scan_int;
- if box(cur_val) = null then
- pdf_error("ext1", "\pdfxform cannot be used with a void box");
- obj_xform_width(k) := width(box(cur_val));
- obj_xform_height(k) := height(box(cur_val));
- obj_xform_depth(k) := depth(box(cur_val));
- obj_xform_box(k) := box(cur_val); {save pointer to the box}
- box(cur_val) := null;
- pdf_last_xform := k;
-end
-
-@ @<Implement \.{\\pdfrefxform}@>=
-begin
- check_pdfoutput("\pdfrefxform", true);
- scan_int;
- pdf_check_obj(obj_type_xform, cur_val);
- new_whatsit(pdf_refxform_node, pdf_refxform_node_size);
- pdf_xform_objnum(tail) := cur_val;
- pdf_width(tail) := obj_xform_width(cur_val);
- pdf_height(tail) := obj_xform_height(cur_val);
- pdf_depth(tail) := obj_xform_depth(cur_val);
-end
-
-@ \.{\\pdfximage} and \.{\\pdfrefximage} are similiar to \.{\\pdfxform} and
- \.{\\pdfrefxform}. As we have to scan |<rule spec>| quite often, it is better
- have a |rule_node| that holds the most recently scanned |<rule spec>|.
-
-@<Glob...@>=
-@!pdf_last_ximage: integer;
-@!pdf_last_ximage_pages: integer;
-@!pdf_last_ximage_colordepth: integer;
-@!alt_rule: pointer;
-@!pdf_last_pdf_box_spec: integer;
-
-@ @<Set init...@>=
-alt_rule := null;
-
-@ @<Declare procedures needed in |do_ext...@>=
-procedure scale_image(n: integer);
-var x, y, xr, yr: integer; {size and resolution of image}
- w, h: scaled; {indeed size corresponds to image resolution}
- default_res: integer;
-begin
- x := image_width(obj_ximage_data(n));
- y := image_height(obj_ximage_data(n));
- xr := image_x_res(obj_ximage_data(n));
- yr := image_y_res(obj_ximage_data(n));
- if (xr > 65535) or (yr > 65535) then begin
- xr := 0;
- yr := 0;
- pdf_warning("ext1", "too large image resolution ignored", true);
- end;
- if (x <= 0) or (y <= 0) or (xr < 0) or (yr < 0) then
- pdf_error("ext1", "invalid image dimensions");
- if is_pdf_image(obj_ximage_data(n)) then begin
- w := x;
- h := y;
- end
- else begin
- default_res := fix_int(pdf_image_resolution, 0, 65535);
- if (default_res > 0) and ((xr = 0) or (yr = 0)) then begin
- xr := default_res;
- yr := default_res;
- end;
- if is_running(obj_ximage_width(n)) and
- is_running(obj_ximage_height(n)) then
- begin
- if (xr > 0) and (yr > 0) then begin
- w := ext_xn_over_d(one_hundred_inch, x, 100*xr);
- h := ext_xn_over_d(one_hundred_inch, y, 100*yr);
- end
- else begin
- w := ext_xn_over_d(one_hundred_inch, x, 7200);
- h := ext_xn_over_d(one_hundred_inch, y, 7200);
- end;
- end;
- end;
- if is_running(obj_ximage_width(n)) and is_running(obj_ximage_height(n)) and
- is_running(obj_ximage_depth(n)) then begin
- obj_ximage_width(n) := w;
- obj_ximage_height(n) := h;
- obj_ximage_depth(n) := 0;
- end
- else if is_running(obj_ximage_width(n)) then begin
- {image depth or height is explicitly specified}
- if is_running(obj_ximage_height(n)) then begin
- {image depth is explicitly specified}
- obj_ximage_width(n) := ext_xn_over_d(h, x, y);
- obj_ximage_height(n) := h - obj_ximage_depth(n);
- end
- else if is_running(obj_ximage_depth(n)) then begin
- {image height is explicitly specified}
- obj_ximage_width(n) := ext_xn_over_d(obj_ximage_height(n), x, y);
- obj_ximage_depth(n) := 0;
- end
- else begin
- {both image depth and height are explicitly specified}
- obj_ximage_width(n) := ext_xn_over_d(obj_ximage_height(n) +
- obj_ximage_depth(n), x, y);
- end;
- end
- else begin
- {image width is explicitly specified}
- if is_running(obj_ximage_height(n)) and
- is_running(obj_ximage_depth(n)) then begin
- {both image depth and height are not specified}
- obj_ximage_height(n) := ext_xn_over_d(obj_ximage_width(n), y, x);
- obj_ximage_depth(n) := 0;
- end
- {image depth is explicitly specified}
- else if is_running(obj_ximage_height(n)) then begin
- obj_ximage_height(n) :=
- ext_xn_over_d(obj_ximage_width(n), y, x) - obj_ximage_depth(n);
- end
- {image height is explicitly specified}
- else if is_running(obj_ximage_depth(n)) then begin
- obj_ximage_depth(n) := 0;
- end
- {both image depth and height are explicitly specified}
- else
- do_nothing;
- end;
-end;
-
-procedure scan_pdf_box_spec; {scans pdf-box-spec to |pdf_last_pdf_box_spec|}
-begin
- pdf_last_pdf_box_spec := pdf_pdf_box_spec_crop;
-
- if scan_keyword("mediabox") then
- pdf_last_pdf_box_spec := pdf_pdf_box_spec_media
- else if scan_keyword("cropbox") then
- pdf_last_pdf_box_spec := pdf_pdf_box_spec_crop
- else if scan_keyword("bleedbox") then
- pdf_last_pdf_box_spec := pdf_pdf_box_spec_bleed
- else if scan_keyword("trimbox") then
- pdf_last_pdf_box_spec := pdf_pdf_box_spec_trim
- else if scan_keyword("artbox") then
- pdf_last_pdf_box_spec := pdf_pdf_box_spec_art
-end;
-
-procedure scan_alt_rule; {scans rule spec to |alt_rule|}
-label reswitch;
-begin
- if alt_rule = null then
- alt_rule := new_rule;
- width(alt_rule) := null_flag;
- height(alt_rule) := null_flag;
- depth(alt_rule) := null_flag;
-reswitch:
- if scan_keyword("width") then begin
- scan_normal_dimen;
- width(alt_rule) := cur_val;
- goto reswitch;
- end;
- if scan_keyword("height") then begin
- scan_normal_dimen;
- height(alt_rule) := cur_val;
- goto reswitch;
- end;
- if scan_keyword("depth") then begin
- scan_normal_dimen;
- depth(alt_rule) := cur_val;
- goto reswitch;
- end;
-end;
-
-procedure scan_image;
-label reswitch;
-var p: pointer;
- k: integer;
- named: str_number;
- s: str_number;
- page, colorspace: integer;
-begin
- incr(pdf_ximage_count);
- pdf_create_obj(obj_type_ximage, pdf_ximage_count);
- k := obj_ptr;
- obj_data_ptr(k) := pdf_get_mem(pdfmem_ximage_size);
- scan_alt_rule; {scans |<rule spec>| to |alt_rule|}
- obj_ximage_width(k) := width(alt_rule);
- obj_ximage_height(k) := height(alt_rule);
- obj_ximage_depth(k) := depth(alt_rule);
- if scan_keyword("attr") then begin
- scan_pdf_ext_toks;
- obj_ximage_attr(k) := def_ref;
- end
- else
- obj_ximage_attr(k) := null;
- named := 0;
- if scan_keyword("named") then begin
- scan_pdf_ext_toks;
- named := tokens_to_string(def_ref);
- delete_token_ref(def_ref);
- end
- else if scan_keyword("page") then begin
- scan_int;
- page := cur_val;
- end
- else
- page := 1;
- if scan_keyword("colorspace") then begin
- scan_int;
- colorspace := cur_val;
- end
- else
- colorspace := 0;
- scan_pdf_box_spec; {scans pdf-box-spec to |pdf_last_pdf_box_spec|}
- scan_pdf_ext_toks;
- s := tokens_to_string(def_ref);
- delete_token_ref(def_ref);
- if pdf_option_always_use_pdfpagebox <> 0 then begin
- pdf_warning(0,"Primitive \pdfoptionalwaysusepdfpagebox is obsolete; use \pdfforcepagebox instead.",true);
- pdf_force_pagebox := pdf_option_always_use_pdfpagebox;
- pdf_option_always_use_pdfpagebox := 0; {warn once}
- end;
- if pdf_option_pdf_inclusion_errorlevel <> 0 then begin
- pdf_warning(0,"Primitive \pdfoptionpdfinclusionerrorlevel is obsolete; use \pdfinclusionerrorlevel instead.",true);
- pdf_inclusion_errorlevel := pdf_option_pdf_inclusion_errorlevel;
- pdf_option_pdf_inclusion_errorlevel := 0; {warn once}
- end;
- if pdf_force_pagebox > 0 then begin
- print_err("pdfTeX warning (image inclusion): ");
- print ("\pdfforcepagebox is in use (");
- print_int (pdf_force_pagebox);
- print (")");
- print_ln;
- end;
- obj_ximage_data(k) := read_image(s, page, named, colorspace,
- pdf_minor_version,
- pdf_force_pagebox,
- pdf_inclusion_errorlevel);
- if named <> 0 then flush_str(named);
- flush_str(s);
- scale_image(k);
- pdf_last_ximage := k;
- pdf_last_ximage_pages := image_pages(obj_ximage_data(k));
- pdf_last_ximage_colordepth := image_colordepth(obj_ximage_data(k));
-end;
-
-@ @<Implement \.{\\pdfximage}@>=
-begin
- check_pdfoutput("\pdfximage", true);
- check_pdfminorversion;
- scan_image;
-end
-
-@ @<Implement \.{\\pdfrefximage}@>=
-begin
- check_pdfoutput("\pdfrefximage", true);
- scan_int;
- pdf_check_obj(obj_type_ximage, cur_val);
- new_whatsit(pdf_refximage_node, pdf_refximage_node_size);
- pdf_ximage_objnum(tail) := cur_val;
- pdf_width(tail) := obj_ximage_width(cur_val);
- pdf_height(tail) := obj_ximage_height(cur_val);
- pdf_depth(tail) := obj_ximage_depth(cur_val);
-end
-
-@ The following function finds object with identifier |i| and type |t|.
- |i < 0| indicates that |-i| should be treated as a string number. If no
- such object exists then it will be created. This function is used mainly to
- find destination for link annotations and outlines; however it is also used
- in |pdf_ship_out| (to check whether a Page object already exists) so we need
- to declare it together with subroutines needed in |pdf_hlist_out| and
- |pdf_vlist_out|.
-
-@<Declare procedures that need to be declared forward for pdftex@>=
-function find_obj(t, i: integer; byname: boolean): integer;
-begin
- find_obj := avl_find_obj(t, i, byname);
-end;
-
-procedure flush_str(s: str_number); {flush a string if possible}
-begin
- if flushable(s) then
- flush_string;
-end;
-
-function get_obj(t, i: integer; byname: boolean): integer;
-var r: integer;
- s: str_number;
-begin
- if byname > 0 then begin
- s := tokens_to_string(i);
- r := find_obj(t, s, true);
- end
- else begin
- s := 0;
- r := find_obj(t, i, false);
- end;
- if r = 0 then begin
- if byname > 0 then begin
- pdf_create_obj(t, -s);
- s := 0;
- end
- else
- pdf_create_obj(t, i);
- r := obj_ptr;
- if t = obj_type_dest then
- obj_dest_ptr(r) := null;
- end;
- if s <> 0 then
- flush_str(s);
- get_obj := r;
-end;
-
-function get_microinterval:integer;
-var s,@!m:integer; {seconds and microseconds}
-begin
- seconds_and_micros(s,m);
- if (s-epochseconds)>32767 then
- get_microinterval := max_integer
- else if (microseconds>m) then
- get_microinterval := ((s-1-epochseconds)*65536)+ (((m+1000000-microseconds)/100)*65536)/10000
- else
- get_microinterval := ((s-epochseconds)*65536) + (((m-microseconds)/100)*65536)/10000;
-end;
-
+@ @<(\pdfTeX) Output a substitution, |goto continue| if not possible@>=
+ begin
+ @<Get substitution information, check it, goto |found|
+ if all is ok, otherwise goto |continue|@>;
+found: @<Print character substition tracing log@>;
+ @<(\pdfTeX) Rebuild character using substitution information@>;
+ end
-@ @<Declare procedures needed in |do_ext...@>=
-function scan_action: pointer; {read an action specification}
-var p, t: integer;
- s: str_number;
-begin
- p := get_node(pdf_action_size);
- scan_action := p;
- pdf_action_file(p) := null;
- pdf_action_refcount(p) := null;
- if scan_keyword("user") then
- pdf_action_type(p) := pdf_action_user
- else if scan_keyword("goto") then
- pdf_action_type(p) := pdf_action_goto
- else if scan_keyword("thread") then
- pdf_action_type(p) := pdf_action_thread
- else
- pdf_error("ext1", "action type missing");
- if pdf_action_type(p) = pdf_action_user then begin
- scan_pdf_ext_toks;
- pdf_action_user_tokens(p) := def_ref;
- return;
- end;
- if scan_keyword("file") then begin
- scan_pdf_ext_toks;
- pdf_action_file(p) := def_ref;
- end;
- if scan_keyword("page") then begin
- if pdf_action_type(p) <> pdf_action_goto then
- pdf_error("ext1", "only GoTo action can be used with `page'");
- pdf_action_type(p) := pdf_action_page;
- scan_int;
- if cur_val <= 0 then
- pdf_error("ext1", "page number must be positive");
- pdf_action_id(p) := cur_val;
- pdf_action_named_id(p) := 0;
- scan_pdf_ext_toks;
- pdf_action_page_tokens(p) := def_ref;
- end
- else if scan_keyword("name") then begin
- scan_pdf_ext_toks;
- pdf_action_named_id(p) := 1;
- pdf_action_id(p) := def_ref;
- end
- else if scan_keyword("num") then begin
- if (pdf_action_type(p) = pdf_action_goto) and
- (pdf_action_file(p) <> null) then
- pdf_error("ext1",
- "`goto' option cannot be used with both `file' and `num'");
- scan_int;
- if cur_val <= 0 then
- pdf_error("ext1", "num identifier must be positive");
- pdf_action_named_id(p) := 0;
- pdf_action_id(p) := cur_val;
+@ @<(\pdfTeX) Rebuild character using substitution information@>=
+ base_x_height:=x_height(f);
+ base_slant:=slant(f)/float_constant(65536);
+@^real division@>
+ accent_slant:=base_slant; {slant of accent character font}
+ base_width:=char_width(f)(ib_c);
+ base_height:=char_height(f)(height_depth(ib_c));
+ accent_width:=char_width(f)(ia_c);
+ accent_height:=char_height(f)(height_depth(ia_c));
+ @/{compute necessary horizontal shift (don't forget slant)}@/
+ delta:=round((base_width-accent_width)/float_constant(2)+
+ base_height*base_slant-base_x_height*accent_slant);
+@^real multiplication@>
+@^real addition@>
+ @/{1. For centering/horizontal shifting insert a kern node.}@/
+ cur_h:=cur_h+delta;
+ @/{2. Then insert the accent character possibly shifted up or down.}@/
+ if ((base_height<>base_x_height) and (accent_height>0)) then
+ begin {the accent must be shifted up or down}
+ cur_v:=base_line+(base_x_height-base_height);
+ output_one_char(accent_c);
+ cur_v:=base_line;
end
- else
- pdf_error("ext1", "identifier type missing");
- if scan_keyword("newwindow") then begin
- pdf_action_new_window(p) := 1;
- @<Scan an optional space@>; end
- else if scan_keyword("nonewwindow") then begin
- pdf_action_new_window(p) := 2;
- @<Scan an optional space@>; end
- else
- pdf_action_new_window(p) := 0;
- if (pdf_action_new_window(p) > 0) and
- (((pdf_action_type(p) <> pdf_action_goto) and
- (pdf_action_type(p) <> pdf_action_page)) or
- (pdf_action_file(p) = null)) then
- pdf_error("ext1",
- "`newwindow'/`nonewwindow' must be used with `goto' and `file' option");
-end;
-
-procedure new_annot_whatsit(w, s: small_number); {create a new whatsit node for
-annotation}
-var p: pointer;
-begin
- new_whatsit(w, s);
- scan_alt_rule; {scans |<rule spec>| to |alt_rule|}
- pdf_width(tail) := width(alt_rule);
- pdf_height(tail) := height(alt_rule);
- pdf_depth(tail) := depth(alt_rule);
- if (w = pdf_start_link_node) then begin
- if scan_keyword("attr") then begin
- scan_pdf_ext_toks;
- pdf_link_attr(tail) := def_ref;
- end
- else
- pdf_link_attr(tail) := null;
- end;
- if (w = pdf_thread_node) or (w = pdf_start_thread_node) then begin
- if scan_keyword("attr") then begin
- scan_pdf_ext_toks;
- pdf_thread_attr(tail) := def_ref;
- end
- else
- pdf_thread_attr(tail) := null;
+ else begin
+ output_one_char(accent_c);
end;
-end;
-
-@ @<Glob...@>=
-@!pdf_last_annot: integer;
-
-@ @<Implement \.{\\pdfannot}@>=
-begin
- check_pdfoutput("\pdfannot", true);
- if scan_keyword("reserveobjnum") then begin
- pdf_last_annot := pdf_new_objnum;
- @<Scan an optional space@>; end
- else begin
- if scan_keyword("useobjnum") then begin
- scan_int;
- k := cur_val;
- if (k <= 0) or (k > obj_ptr) or (obj_annot_ptr(k) <> 0) then
- pdf_error("ext1", "invalid object number");
- end
- else
- k := pdf_new_objnum;
- new_annot_whatsit(pdf_annot_node, pdf_annot_node_size);
- pdf_annot_objnum(tail) := k;
- scan_pdf_ext_toks;
- pdf_annot_data(tail) := def_ref;
- pdf_last_annot := k;
- end
-end
-
-@ @<Implement \.{\\pdfstartlink}@>=
-begin
- check_pdfoutput("\pdfstartlink", true);
- if abs(mode) = vmode then
- pdf_error("ext1", "\pdfstartlink cannot be used in vertical mode");
- new_annot_whatsit(pdf_start_link_node, pdf_annot_node_size);
- pdf_link_action(tail) := scan_action;
-end
-
-@ @<Implement \.{\\pdfendlink}@>=
-begin
- check_pdfoutput("\pdfendlink", true);
- if abs(mode) = vmode then
- pdf_error("ext1", "\pdfendlink cannot be used in vertical mode");
- new_whatsit(pdf_end_link_node, small_node_size);
-end
+ cur_h:=cur_h+accent_width;
+ @/{3. For centering/horizontal shifting insert another kern node.}@/
+ cur_h:=cur_h+(-accent_width-delta);
+ @/{4. Output the base character.}@/
+ output_one_char(base_c);
+ cur_h:=cur_h+base_width;
-@ @<Declare procedures needed in |do_ext...@>=
-function outline_list_count(p: pointer): integer; {return number of outline
-entries in the same level with |p|}
-var k: integer;
-begin
- k := 1;
- while obj_outline_prev(p) <> 0 do begin
- incr(k);
- p := obj_outline_prev(p);
- end;
- outline_list_count := k;
-end;
+@ The |pdf_vlist_out| routine is similar to |pdf_hlist_out|, but a bit simpler.
+@z
-@ @<Implement \.{\\pdfoutline}@>=
-begin
- check_pdfoutput("\pdfoutline", true);
- if scan_keyword("attr") then begin
- scan_pdf_ext_toks;
- r := def_ref;
- end
- else
- r := 0;
- p := scan_action;
- if scan_keyword("count") then begin
- scan_int;
- i := cur_val;
- end
- else
- i := 0;
- scan_pdf_ext_toks;
- q := def_ref;
- pdf_new_obj(obj_type_others, 0);
- j := obj_ptr;
- write_action(p);
- pdf_end_obj;
- delete_action_ref(p);
- pdf_create_obj(obj_type_outline, 0);
- k := obj_ptr;
- obj_outline_ptr(k) := pdf_get_mem(pdfmem_outline_size);
- obj_outline_action_objnum(k) := j;
- obj_outline_count(k) := i;
- pdf_new_obj(obj_type_others, 0);
- pdf_print_str_ln(tokens_to_string(q));
- flush_str(last_tokens_string);
- delete_token_ref(q);
- pdf_end_obj;
- obj_outline_title(k) := obj_ptr;
- obj_outline_prev(k) := 0;
- obj_outline_next(k) := 0;
- obj_outline_first(k) := 0;
- obj_outline_last(k) := 0;
- obj_outline_parent(k) := pdf_parent_outline;
- obj_outline_attr(k) := r;
- if pdf_first_outline = 0 then
- pdf_first_outline := k;
- if pdf_last_outline = 0 then begin
- if pdf_parent_outline <> 0 then
- obj_outline_first(pdf_parent_outline) := k;
- end
- else begin
- obj_outline_next(pdf_last_outline) := k;
- obj_outline_prev(k) := pdf_last_outline;
- end;
- pdf_last_outline := k;
- if obj_outline_count(k) <> 0 then begin
- pdf_parent_outline := k;
- pdf_last_outline := 0;
+@x [49.1259]
+ begin if s>0 then
+ begin if s=font_size[f] then goto common_ending;
+ end
+ else if font_size[f]=xn_over_d(font_dsize[f],-s,1000) then
+ goto common_ending;
end
- else if (pdf_parent_outline <> 0) and
- (outline_list_count(k) = abs(obj_outline_count(pdf_parent_outline))) then
+@y
begin
- j := pdf_last_outline;
- repeat
- obj_outline_last(pdf_parent_outline) := j;
- j := pdf_parent_outline;
- pdf_parent_outline := obj_outline_parent(pdf_parent_outline);
- until (pdf_parent_outline = 0) or
- (outline_list_count(j) < abs(obj_outline_count(pdf_parent_outline)));
- if pdf_parent_outline = 0 then
- pdf_last_outline := pdf_first_outline
- else
- pdf_last_outline := obj_outline_first(pdf_parent_outline);
- while obj_outline_next(pdf_last_outline) <> 0 do
- pdf_last_outline := obj_outline_next(pdf_last_outline);
- end;
-end
-
-@ When a destination is created we need to check whether another destination
-with the same identifier already exists and give a warning if needed.
-
-@<Declare procedures needed in |pdf_hlist_out|, |pdf_vlist_out|@>=
-procedure warn_dest_dup(id: integer; byname: small_number; s1, s2: str_number);
-begin
- pdf_warning(s1, "destination with the same identifier (", false);
- if byname > 0 then begin
- print("name");
- print_mark(id);
- end
- else begin
- print("num");
- print_int(id);
- end;
- print(") ");
- print(s2);
- print_ln;
- show_context;
-end;
-
-@ Notice that |scan_keyword| doesn't care if two words have same prefix; so
-we should be careful when scan keywords with same prefix. The main rule: if
-there are two or more keywords with the same prefix, then always test in
-order from the longest one to the shortest one.
-
-@<Implement \.{\\pdfdest}@>=
-begin
- check_pdfoutput("\pdfdest", true);
- q := tail;
- new_whatsit(pdf_dest_node, pdf_dest_node_size);
- if scan_keyword("num") then begin
- scan_int;
- if cur_val <= 0 then
- pdf_error("ext1", "num identifier must be positive");
- if cur_val > max_halfword then
- pdf_error("ext1", "number too big");
- pdf_dest_id(tail) := cur_val;
- pdf_dest_named_id(tail) := 0;
- end
- else if scan_keyword("name") then begin
- scan_pdf_ext_toks;
- pdf_dest_id(tail) := def_ref;
- pdf_dest_named_id(tail) := 1;
- end
- else
- pdf_error("ext1", "identifier type missing");
- if scan_keyword("xyz") then begin
- pdf_dest_type(tail) := pdf_dest_xyz;
- if scan_keyword("zoom") then begin
- scan_int;
- if cur_val > max_halfword then
- pdf_error("ext1", "number too big");
- pdf_dest_xyz_zoom(tail) := cur_val;
- end
- else
- pdf_dest_xyz_zoom(tail) := null;
- end
- else if scan_keyword("fitbh") then
- pdf_dest_type(tail) := pdf_dest_fitbh
- else if scan_keyword("fitbv") then
- pdf_dest_type(tail) := pdf_dest_fitbv
- else if scan_keyword("fitb") then
- pdf_dest_type(tail) := pdf_dest_fitb
- else if scan_keyword("fith") then
- pdf_dest_type(tail) := pdf_dest_fith
- else if scan_keyword("fitv") then
- pdf_dest_type(tail) := pdf_dest_fitv
- else if scan_keyword("fitr") then
- pdf_dest_type(tail) := pdf_dest_fitr
- else if scan_keyword("fit") then
- pdf_dest_type(tail) := pdf_dest_fit
- else
- pdf_error("ext1", "destination type missing");
- @<Scan an optional space@>;
- if pdf_dest_type(tail) = pdf_dest_fitr then begin
- scan_alt_rule; {scans |<rule spec>| to |alt_rule|}
- pdf_width(tail) := width(alt_rule);
- pdf_height(tail) := height(alt_rule);
- pdf_depth(tail) := depth(alt_rule);
- end;
- if pdf_dest_named_id(tail) <> 0 then begin
- i := tokens_to_string(pdf_dest_id(tail));
- k := find_obj(obj_type_dest, i, true);
- flush_str(i);
- end
- else
- k := find_obj(obj_type_dest, pdf_dest_id(tail), false);
- if (k <> 0) and (obj_dest_ptr(k) <> null) then begin
- warn_dest_dup(pdf_dest_id(tail), pdf_dest_named_id(tail),
- "ext4", "has been already used, duplicate ignored");
- flush_node_list(tail);
- tail := q;
- link(q) := null;
- end;
-end
-
-@ @<Declare procedures needed in |do_ext...@>=
-procedure scan_thread_id;
-begin
- if scan_keyword("num") then begin
- scan_int;
- if cur_val <= 0 then
- pdf_error("ext1", "num identifier must be positive");
- if cur_val > max_halfword then
- pdf_error("ext1", "number too big");
- pdf_thread_id(tail) := cur_val;
- pdf_thread_named_id(tail) := 0;
- end
- else if scan_keyword("name") then begin
- scan_pdf_ext_toks;
- pdf_thread_id(tail) := def_ref;
- pdf_thread_named_id(tail) := 1;
- end
- else
- pdf_error("ext1", "identifier type missing");
-end;
-
-@ @<Implement \.{\\pdfthread}@>=
-begin
- check_pdfoutput("\pdfthread", true);
- new_annot_whatsit(pdf_thread_node, pdf_thread_node_size);
- scan_thread_id;
-end
-
-@ @<Implement \.{\\pdfstartthread}@>=
-begin
- check_pdfoutput("\pdfstartthread", true);
- new_annot_whatsit(pdf_start_thread_node, pdf_thread_node_size);
- scan_thread_id;
-end
-
-@ @<Implement \.{\\pdfendthread}@>=
-begin
- check_pdfoutput("\pdfendthread", true);
- new_whatsit(pdf_end_thread_node, small_node_size);
-end
-
-@ @<Glob...@>=
-@!pdf_last_x_pos: integer;
-@!pdf_last_y_pos: integer;
-
-@ @<Implement \.{\\pdfsavepos}@>=
-begin
- check_pdfoutput("\pdfsavepos", true);
- new_whatsit(pdf_save_pos_node, small_node_size);
-end
-
-@ To implement primitives as \.{\\pdfinfo}, \.{\\pdfcatalog} or
-\.{\\pdfnames} we need to concatenate tokens lists.
-
-@<Declare procedures needed in |do_ext...@>=
-function concat_tokens(q, r: pointer): pointer; {concat |q| and |r| and
-returns the result tokens list}
-var p: pointer;
-begin
- if q = null then begin
- concat_tokens := r;
- return;
- end;
- p := q;
- while link(p) <> null do
- p := link(p);
- link(p) := link(r);
- free_avail(r);
- concat_tokens := q;
-end;
-
-@ @<Implement \.{\\pdfinfo}@>=
-begin
- check_pdfoutput("\pdfinfo", false);
- scan_pdf_ext_toks;
- if pdf_output > 0 then
- pdf_info_toks := concat_tokens(pdf_info_toks, def_ref);
-end
-
-@ @<Implement \.{\\pdfcatalog}@>=
-begin
- check_pdfoutput("\pdfcatalog", false);
- scan_pdf_ext_toks;
- if pdf_output > 0 then
- pdf_catalog_toks := concat_tokens(pdf_catalog_toks, def_ref);
- if scan_keyword("openaction") then
- if pdf_catalog_openaction <> 0 then
- pdf_error("ext1", "duplicate of openaction")
- else begin
- p := scan_action;
- pdf_new_obj(obj_type_others, 0);
- if pdf_output > 0 then
- pdf_catalog_openaction := obj_ptr;
- write_action(p);
- pdf_end_obj;
- delete_action_ref(p);
- end;
-end
-
-@ @<Implement \.{\\pdfnames}@>=
-begin
- check_pdfoutput("\pdfnames", true);
- scan_pdf_ext_toks;
- pdf_names_toks := concat_tokens(pdf_names_toks, def_ref);
-end
-
-@ @<Implement \.{\\pdftrailer}@>=
-begin
- check_pdfoutput("\pdftrailer", false);
- scan_pdf_ext_toks;
- if pdf_output > 0 then
- pdf_trailer_toks := concat_tokens(pdf_trailer_toks, def_ref);
-end
-
-@ @<Implement \.{\\pdfescapestring}@>=
-begin
- scan_pdf_ext_toks;
- escapestr(tokens_to_string(def_ref));
- flush_str(last_tokens_string);
- delete_token_ref(def_ref);
-end
-
-@ @<Implement \.{\\pdfescapename}@>=
-begin
- scan_pdf_ext_toks;
- escapename(tokens_to_string(def_ref));
- flush_str(last_tokens_string);
- delete_token_ref(def_ref);
-end
-
-@ @<Glob...@>=
-@!pdf_retval: integer; {global multi-purpose return value}
-
-@ @<Implement \.{\\pdfstrcmp}@>=
-compare_strings
-
-@ @<Set initial values of key variables@>=
- seconds_and_micros(epochseconds,microseconds);
-
-@ @<Implement \.{\\pdfresettimer}@>=
-begin
- seconds_and_micros(epochseconds,microseconds);
-end
-
-
-@ The following subroutines are about PDF-specific font issues.
-
-@<Declare procedures needed in |do_ext...@>=
-procedure pdf_include_chars;
-var s: str_number;
- k: pool_pointer; {running indices}
- f: internal_font_number;
-begin
- scan_font_ident;
- f := cur_val;
- if f = null_font then
- pdf_error("font", "invalid font identifier");
- pdf_check_vf(f);
- if not font_used[f] then
- pdf_init_font(f);
- scan_pdf_ext_toks;
- s := tokens_to_string(def_ref);
- delete_token_ref(def_ref);
- k := str_start[s];
- while k < str_start[s + 1] do begin
- pdf_mark_char(f, str_pool[k]);
- incr(k);
- end;
- flush_str(s);
-end;
-
-
-@ @<Implement \.{\\pdfincludechars}@>=
-begin
- check_pdfoutput("\pdfincludechars", true);
- pdf_include_chars;
-end
-
-@ @<Implement \.{\\pdffontattr}@>=
-begin
- check_pdfoutput("\pdffontattr", true);
- scan_font_ident;
- k := cur_val;
- if k = null_font then
- pdf_error("font", "invalid font identifier");
- scan_pdf_ext_toks;
- pdf_font_attr[k] := tokens_to_string(def_ref);
-end
-
-@ @<Implement \.{\\pdfmapfile}@>=
-begin
- check_pdfoutput("\pdfmapfile", true);
- scan_pdf_ext_toks;
- pdfmapfile(def_ref);
- delete_token_ref(def_ref);
-end
-
-@ @<Implement \.{\\pdfmapline}@>=
-begin
- check_pdfoutput("\pdfmapline", true);
- scan_pdf_ext_toks;
- pdfmapline(def_ref);
- delete_token_ref(def_ref);
-end
-
-@ The following function are needed for outputing article thread.
-
-@<Declare procedures needed in |do_ext...@>=
-procedure thread_title(thread: integer);
-begin
- pdf_print("/Title (");
- if obj_info(thread) < 0 then
- pdf_print(-obj_info(thread))
- else
- pdf_print_int(obj_info(thread));
- pdf_print_ln(")");
-end;
-
-procedure pdf_fix_thread(thread: integer);
-var a: pointer;
-begin
- pdf_warning("thread", "destination ", false);
- if obj_info(thread) < 0 then begin
- print("name{");
- print(-obj_info(thread));
- print("}");
- end
- else begin
- print("num");
- print_int(obj_info(thread));
- end;
- print(" has been referenced but does not exist, replaced by a fixed one");
- print_ln; print_ln;
- pdf_new_dict(obj_type_others, 0);
- a := obj_ptr;
- pdf_indirect_ln("T", thread);
- pdf_indirect_ln("V", a);
- pdf_indirect_ln("N", a);
- pdf_indirect_ln("P", head_tab[obj_type_page]);
- pdf_print("/R [0 0 ");
- pdf_print_bp(pdf_page_width); pdf_out(" ");
- pdf_print_bp(pdf_page_height);
- pdf_print_ln("]");
- pdf_end_dict;
- pdf_begin_dict(thread);
- pdf_print_ln("/I << ");
- thread_title(thread);
- pdf_print_ln(">>");
- pdf_indirect_ln("F", a);
- pdf_end_dict;
-end;
+ if pdf_font_step[f] = 0 then begin
+ if s>0 then
+ begin if s=font_size[f] then goto common_ending;
+ end
+ else if font_size[f]=xn_over_d(font_dsize[f],-s,1000) then
+ goto common_ending;
+ end
+ end
+@z
+
+@x (WEB2C!)
+param_base:=xmalloc_array(integer, font_max);
+
+undump_things(font_check[null_font], font_ptr+1-null_font);
+@y
+param_base:=xmalloc_array(integer, font_max);
+
+pdf_char_used:=xmalloc_array(char_used_array, font_max);
+pdf_font_size:=xmalloc_array(scaled, font_max);
+pdf_font_num:=xmalloc_array(integer, font_max);
+pdf_font_map:=xmalloc_array(fm_entry_ptr, font_max);
+pdf_font_type:=xmalloc_array(eight_bits, font_max);
+pdf_font_attr:=xmalloc_array(str_number, font_max);
+pdf_font_blink:=xmalloc_array(internal_font_number, font_max);
+pdf_font_elink:=xmalloc_array(internal_font_number, font_max);
+pdf_font_stretch:=xmalloc_array(integer, font_max);
+pdf_font_shrink:=xmalloc_array(integer, font_max);
+pdf_font_step:=xmalloc_array(integer, font_max);
+pdf_font_expand_ratio:=xmalloc_array(integer, font_max);
+pdf_font_auto_expand:=xmalloc_array(boolean, font_max);
+pdf_font_lp_base:=xmalloc_array(integer, font_max);
+pdf_font_rp_base:=xmalloc_array(integer, font_max);
+pdf_font_ef_base:=xmalloc_array(integer, font_max);
+pdf_font_kn_bs_base:=xmalloc_array(integer, font_max);
+pdf_font_st_bs_base:=xmalloc_array(integer, font_max);
+pdf_font_sh_bs_base:=xmalloc_array(integer, font_max);
+pdf_font_kn_bc_base:=xmalloc_array(integer, font_max);
+pdf_font_kn_ac_base:=xmalloc_array(integer, font_max);
+vf_packet_base:=xmalloc_array(integer, font_max);
+vf_default_font:=xmalloc_array(internal_font_number, font_max);
+vf_local_font_num:=xmalloc_array(internal_font_number, font_max);
+vf_e_fnts:=xmalloc_array(integer, font_max);
+vf_i_fnts:=xmalloc_array(internal_font_number, font_max);
+
+for font_k := font_base to font_max do begin
+ for k := 0 to 31 do
+ pdf_char_used[font_k, k] := 0;
+ pdf_font_size[font_k] := 0;
+ pdf_font_num[font_k] := 0;
+ pdf_font_map[font_k] := 0;
+ pdf_font_type[font_k] := new_font_type;
+ pdf_font_attr[font_k] := "";
+ pdf_font_blink[font_k] := null_font;
+ pdf_font_elink[font_k] := null_font;
+ pdf_font_stretch[font_k] := null_font;
+ pdf_font_shrink[font_k] := null_font;
+ pdf_font_step[font_k] := 0;
+ pdf_font_expand_ratio[font_k] := 0;
+ pdf_font_auto_expand[font_k] := false;
+ pdf_font_lp_base[font_k] := 0;
+ pdf_font_rp_base[font_k] := 0;
+ pdf_font_ef_base[font_k] := 0;
+ pdf_font_kn_bs_base[font_k] := 0;
+ pdf_font_st_bs_base[font_k] := 0;
+ pdf_font_sh_bs_base[font_k] := 0;
+ pdf_font_kn_bc_base[font_k] := 0;
+ pdf_font_kn_ac_base[font_k] := 0;
+end;
+
+make_pdftex_banner;
+undump_things(font_check[null_font], font_ptr+1-null_font);
+@z
+
+@x [51.1]
+ setup_bound_var (0)('hash_extra')(hash_extra);
+
+@y
+ setup_bound_var (0)('hash_extra')(hash_extra);
+ setup_bound_var (72)('pk_dpi')(pk_dpi);
+@z
+
+@x [51.2]
+ const_chk (hash_extra);
+ if error_line > ssup_error_line then error_line := ssup_error_line;
+@y
+ const_chk (hash_extra);
+ const_chk (obj_tab_size);
+ const_chk (pdf_mem_size);
+ const_chk (dest_names_size);
+ const_chk (pk_dpi);
+ if error_line > ssup_error_line then error_line := ssup_error_line;
+@z
+
+@x [51.1332] l.24203 (ca.) texarray
+ line_stack:=xmalloc_array (integer, max_in_open);
+@y
+ line_stack:=xmalloc_array (integer, max_in_open);
+ eof_seen:=xmalloc_array (boolean, max_in_open);
+ grp_stack:=xmalloc_array (save_pointer, max_in_open);
+ if_stack:=xmalloc_array (pointer, max_in_open);
+@z
+
+@x [51.3]
+ hyph_link :=xmalloc_array (hyph_pointer, hyph_size);
+@y
+ hyph_link :=xmalloc_array (hyph_pointer, hyph_size);
+ obj_tab:=xmalloc_array (obj_entry, inf_obj_tab_size); {will grow dynamically}
+ pdf_mem:=xmalloc_array (integer, inf_pdf_mem_size); {will grow dynamically}
+ dest_names:=xmalloc_array (dest_name_entry, inf_dest_names_size); {will grow dynamically}
+ pdf_op_buf:=xmalloc_array (eight_bits, pdf_op_buf_size);
+ pdf_os_buf:=xmalloc_array (eight_bits, inf_pdf_os_buf_size); {will grow dynamically}
+ pdf_os_objnum:=xmalloc_array (integer, pdf_os_max_objs);
+ pdf_os_objoff:=xmalloc_array (integer, pdf_os_max_objs);
+@z
+
+@x [51.1337] l.24371 (ca.) texarray
+ trie_root:=0; trie_c[0]:=si(0); trie_ptr:=0;
+@y
+ trie_root:=0; trie_c[0]:=si(0); trie_ptr:=0;
+ hyph_root:=0; hyph_start:=0;
+@z
+
+
+@x (WEB2C!)
+ param_base:=xmalloc_array(integer, font_max);
+
+ font_ptr:=null_font; fmem_ptr:=7;
+@y
+param_base:=xmalloc_array(integer, font_max);
+
+pdf_char_used:=xmalloc_array(char_used_array,font_max);
+pdf_font_size:=xmalloc_array(scaled,font_max);
+pdf_font_num:=xmalloc_array(integer,font_max);
+pdf_font_map:=xmalloc_array(fm_entry_ptr,font_max);
+pdf_font_type:=xmalloc_array(eight_bits,font_max);
+pdf_font_attr:=xmalloc_array(str_number,font_max);
+pdf_font_blink:=xmalloc_array(internal_font_number,font_max);
+pdf_font_elink:=xmalloc_array(internal_font_number,font_max);
+pdf_font_stretch:=xmalloc_array(integer,font_max);
+pdf_font_shrink:=xmalloc_array(integer,font_max);
+pdf_font_step:=xmalloc_array(integer,font_max);
+pdf_font_expand_ratio:=xmalloc_array(integer,font_max);
+pdf_font_auto_expand:=xmalloc_array(boolean,font_max);
+pdf_font_lp_base:=xmalloc_array(integer,font_max);
+pdf_font_rp_base:=xmalloc_array(integer,font_max);
+pdf_font_ef_base:=xmalloc_array(integer,font_max);
+pdf_font_kn_bs_base:=xmalloc_array(integer, font_max);
+pdf_font_st_bs_base:=xmalloc_array(integer, font_max);
+pdf_font_sh_bs_base:=xmalloc_array(integer, font_max);
+pdf_font_kn_bc_base:=xmalloc_array(integer, font_max);
+pdf_font_kn_ac_base:=xmalloc_array(integer, font_max);
+vf_packet_base:=xmalloc_array(integer,font_max);
+vf_default_font:=xmalloc_array(internal_font_number,font_max);
+vf_local_font_num:=xmalloc_array(internal_font_number,font_max);
+vf_e_fnts:=xmalloc_array(integer,font_max);
+vf_i_fnts:=xmalloc_array(internal_font_number,font_max);
-procedure out_thread(thread: integer);
-var a, b, c: pointer;
- last_attr: integer;
-begin
- if obj_thread_first(thread) = 0 then begin
- pdf_fix_thread(thread);
- return;
- end;
- pdf_begin_dict(thread);
- a := obj_thread_first(thread);
- b := a;
- last_attr := 0;
- repeat
- if obj_bead_attr(a) <> 0 then
- last_attr := obj_bead_attr(a);
- a := obj_bead_next(a);
- until a = b;
- if last_attr <> 0 then
- pdf_print_ln(last_attr)
- else begin
- pdf_print_ln("/I << ");
- thread_title(thread);
- pdf_print_ln(">>");
- end;
- pdf_indirect_ln("F", a);
- pdf_end_dict;
- repeat
- pdf_begin_dict(a);
- if a = b then
- pdf_indirect_ln("T", thread);
- pdf_indirect_ln("V", obj_bead_prev(a));
- pdf_indirect_ln("N", obj_bead_next(a));
- pdf_indirect_ln("P", obj_bead_page(a));
- pdf_indirect_ln("R", obj_bead_rect(a));
- pdf_end_dict;
- a := obj_bead_next(a);
- until a = b;
+for font_k := font_base to font_max do begin
+ for k := 0 to 31 do
+ pdf_char_used[font_k, k] := 0;
+ pdf_font_size[font_k] := 0;
+ pdf_font_num[font_k] := 0;
+ pdf_font_map[font_k] := 0;
+ pdf_font_type[font_k] := new_font_type;
+ pdf_font_attr[font_k] := "";
+ pdf_font_blink[font_k] := null_font;
+ pdf_font_elink[font_k] := null_font;
+ pdf_font_stretch[font_k] := null_font;
+ pdf_font_shrink[font_k] := null_font;
+ pdf_font_step[font_k] := 0;
+ pdf_font_expand_ratio[font_k] := 0;
+ pdf_font_auto_expand[font_k] := false;
+ pdf_font_lp_base[font_k] := 0;
+ pdf_font_rp_base[font_k] := 0;
+ pdf_font_ef_base[font_k] := 0;
+ pdf_font_kn_bs_base[font_k] := 0;
+ pdf_font_st_bs_base[font_k] := 0;
+ pdf_font_sh_bs_base[font_k] := 0;
+ pdf_font_kn_bc_base[font_k] := 0;
+ pdf_font_kn_ac_base[font_k] := 0;
end;
-@ @<Display <rule spec> for whatsit node created by \pdfTeX@>=
-print("(");
-print_rule_dimen(pdf_height(p));
-print_char("+");
-print_rule_dimen(pdf_depth(p));
-print(")x");
-print_rule_dimen(pdf_width(p))
-@z
-
-@x [1356]
-othercases print("whatsit?")
-@y
-pdf_literal_node: begin
- print_esc("pdfliteral");
- case pdf_literal_mode(p) of
- reset_origin:
- do_nothing;
- direct_page:
- print(" page");
- direct_always:
- print(" direct");
- othercases confusion("literal2")
- endcases;
- print_mark(pdf_literal_data(p));
-end;
-pdf_refobj_node: begin
- print_esc("pdfrefobj");
- if obj_obj_is_stream(pdf_obj_objnum(p)) > 0 then begin
- if obj_obj_stream_attr(pdf_obj_objnum(p)) <> null then begin
- print(" attr");
- print_mark(obj_obj_stream_attr(pdf_obj_objnum(p)));
- end;
- print(" stream");
- end;
- if obj_obj_is_file(pdf_obj_objnum(p)) > 0 then
- print(" file");
- print_mark(obj_obj_data(pdf_obj_objnum(p)));
-end;
-pdf_refxform_node: begin
- print_esc("pdfrefxform");
- print("(");
- print_scaled(obj_xform_height(pdf_xform_objnum(p)));
- print_char("+");
- print_scaled(obj_xform_depth(pdf_xform_objnum(p)));
- print(")x");
- print_scaled(obj_xform_width(pdf_xform_objnum(p)));
-end;
-pdf_refximage_node: begin
- print_esc("pdfrefximage");
- print("(");
- print_scaled(obj_ximage_height(pdf_ximage_objnum(p)));
- print_char("+");
- print_scaled(obj_ximage_depth(pdf_ximage_objnum(p)));
- print(")x");
- print_scaled(obj_ximage_width(pdf_ximage_objnum(p)));
-end;
-pdf_annot_node: begin
- print_esc("pdfannot");
- @<Display <rule spec> for whatsit node created by \pdfTeX@>;
- print_mark(pdf_annot_data(p));
-end;
-pdf_start_link_node: begin
- print_esc("pdflink");
- @<Display <rule spec> for whatsit node created by \pdfTeX@>;
- if pdf_link_attr(p) <> null then begin
- print(" attr");
- print_mark(pdf_link_attr(p));
- end;
- print(" action");
- if pdf_action_type(pdf_link_action(p)) = pdf_action_user then begin
- print(" user");
- print_mark(pdf_action_user_tokens(pdf_link_action(p)));
- return;
- end;
- if pdf_action_file(pdf_link_action(p)) <> null then begin
- print(" file");
- print_mark(pdf_action_file(pdf_link_action(p)));
- end;
- case pdf_action_type(pdf_link_action(p)) of
- pdf_action_goto: begin
- if pdf_action_named_id(pdf_link_action(p)) > 0 then begin
- print(" goto name");
- print_mark(pdf_action_id(pdf_link_action(p)));
- end
- else begin
- print(" goto num");
- print_int(pdf_action_id(pdf_link_action(p)))
- end;
- end;
- pdf_action_page: begin
- print(" page");
- print_int(pdf_action_id(pdf_link_action(p)));
- print_mark(pdf_action_page_tokens(pdf_link_action(p)));
- end;
- pdf_action_thread: begin
- if pdf_action_named_id(pdf_link_action(p)) > 0 then begin
- print(" thread name");
- print_mark(pdf_action_id(pdf_link_action(p)));
- end
- else begin
- print(" thread num");
- print_int(pdf_action_id(pdf_link_action(p)));
- end;
- end;
- othercases pdf_error("displaying", "unknown action type");
- endcases;
-end;
-pdf_end_link_node: print_esc("pdfendlink");
-pdf_dest_node: begin
- print_esc("pdfdest");
- if pdf_dest_named_id(p) > 0 then begin
- print(" name");
- print_mark(pdf_dest_id(p));
- end
- else begin
- print(" num");
- print_int(pdf_dest_id(p));
- end;
- print(" ");
- case pdf_dest_type(p) of
- pdf_dest_xyz: begin
- print("xyz");
- if pdf_dest_xyz_zoom(p) <> null then begin
- print(" zoom");
- print_int(pdf_dest_xyz_zoom(p));
- end;
- end;
- pdf_dest_fitbh: print("fitbh");
- pdf_dest_fitbv: print("fitbv");
- pdf_dest_fitb: print("fitb");
- pdf_dest_fith: print("fith");
- pdf_dest_fitv: print("fitv");
- pdf_dest_fitr: begin
- print("fitr");
- @<Display <rule spec> for whatsit node created by \pdfTeX@>;
- end;
- pdf_dest_fit: print("fit");
- othercases print("unknown!");
- endcases;
-end;
-pdf_thread_node,
-pdf_start_thread_node: begin
- if subtype(p) = pdf_thread_node then
- print_esc("pdfthread")
- else
- print_esc("pdfstartthread");
- print("("); print_rule_dimen(pdf_height(p)); print_char("+");
- print_rule_dimen(pdf_depth(p)); print(")x");
- print_rule_dimen(pdf_width(p));
- if pdf_thread_attr(p) <> null then begin
- print(" attr");
- print_mark(pdf_thread_attr(p));
- end;
- if pdf_thread_named_id(p) > 0 then begin
- print(" name");
- print_mark(pdf_thread_id(p));
- end
- else begin
- print(" num");
- print_int(pdf_thread_id(p));
- end;
-end;
-pdf_end_thread_node: print_esc("pdfendthread");
-pdf_save_pos_node: print_esc("pdfsavepos");
-othercases print("whatsit?")
+font_ptr:=null_font; fmem_ptr:=7;
+make_pdftex_banner;
@z
-@x [1357]
-othercases confusion("ext2")
+@x [53a.1379] l.??? -etex command line switch
+@!init if (buffer[loc]="*")and(format_ident=" (INITEX)") then
@y
-pdf_literal_node: begin
- r := get_node(write_node_size);
- add_token_ref(pdf_literal_data(p));
- words := write_node_size;
-end;
-pdf_refobj_node: begin
- r := get_node(pdf_refobj_node_size);
- words := pdf_refobj_node_size;
-end;
-pdf_refxform_node: begin
- r := get_node(pdf_refxform_node_size);
- words := pdf_refxform_node_size;
-end;
-pdf_refximage_node: begin
- r := get_node(pdf_refximage_node_size);
- words := pdf_refximage_node_size;
-end;
-pdf_annot_node: begin
- r := get_node(pdf_annot_node_size);
- add_token_ref(pdf_annot_data(p));
- words := pdf_annot_node_size;
-end;
-pdf_start_link_node: begin
- r := get_node(pdf_annot_node_size);
- pdf_height(r) := pdf_height(p);
- pdf_depth(r) := pdf_depth(p);
- pdf_width(r) := pdf_width(p);
- pdf_link_attr(r) := pdf_link_attr(p);
- if pdf_link_attr(r) <> null then
- add_token_ref(pdf_link_attr(r));
- pdf_link_action(r) := pdf_link_action(p);
- add_action_ref(pdf_link_action(r));
-end;
-pdf_end_link_node:
- r := get_node(small_node_size);
-pdf_dest_node: begin
- r := get_node(pdf_dest_node_size);
- if pdf_dest_named_id(p) > 0 then
- add_token_ref(pdf_dest_id(p));
- words := pdf_dest_node_size;
-end;
-pdf_thread_node,
-pdf_start_thread_node: begin
- r := get_node(pdf_thread_node_size);
- if pdf_thread_named_id(p) > 0 then
- add_token_ref(pdf_thread_id(p));
- if pdf_thread_attr(p) <> null then
- add_token_ref(pdf_thread_attr(p));
- words := pdf_thread_node_size;
-end;
-pdf_end_thread_node:
- r := get_node(small_node_size);
-pdf_save_pos_node:
- r := get_node(small_node_size);
-othercases confusion("ext2")
+@!init if (etex_p or(buffer[loc]="*"))and(format_ident=" (INITEX)") then
@z
-@x [1358]
-othercases confusion("ext3")
+@x [53a.1379] l.??? -etex command line switch
+ incr(loc); eTeX_mode:=1; {enter extended mode}
@y
-pdf_literal_node: begin
- delete_token_ref(pdf_literal_data(p));
- free_node(p, write_node_size);
-end;
-pdf_refobj_node:
- free_node(p, pdf_refobj_node_size);
-pdf_refxform_node:
- free_node(p, pdf_refxform_node_size);
-pdf_refximage_node:
- free_node(p, pdf_refximage_node_size);
-pdf_annot_node: begin
- delete_token_ref(pdf_annot_data(p));
- free_node(p, pdf_annot_node_size);
-end;
-pdf_start_link_node: begin
- if pdf_link_attr(p) <> null then
- delete_token_ref(pdf_link_attr(p));
- delete_action_ref(pdf_link_action(p));
- free_node(p, pdf_annot_node_size);
-end;
-pdf_end_link_node:
- free_node(p, small_node_size);
-pdf_dest_node: begin
- if pdf_dest_named_id(p) > 0 then
- delete_token_ref(pdf_dest_id(p));
- free_node(p, pdf_dest_node_size);
-end;
-pdf_thread_node,
-pdf_start_thread_node: begin
- if pdf_thread_named_id(p) > 0 then
- delete_token_ref(pdf_thread_id(p));
- if pdf_thread_attr(p) <> null then
- delete_token_ref(pdf_thread_attr(p));
- free_node(p, pdf_thread_node_size);
-end;
-pdf_end_thread_node:
- free_node(p, small_node_size);
-pdf_save_pos_node:
- free_node(p, small_node_size);
-othercases confusion("ext3")
+ if (buffer[loc]="*") then incr(loc);
+ eTeX_mode:=1; {enter extended mode}
@z
-@x [1359]
-@ @<Incorporate a whatsit node into a vbox@>=do_nothing
+@x [53a.1383] l.??? -etex command line switch
+@!eTeX_mode: 0..1; {identifies compatibility and extended mode}
@y
-@ @<Incorporate a whatsit node into a vbox@>=
-if (subtype(p) = pdf_refxform_node) or (subtype(p) = pdf_refximage_node) then
-begin x:=x+d+pdf_height(p); d:=pdf_depth(p);
-s:=0;
-if pdf_width(p)+s>w then w:=pdf_width(p)+s;
-end
+@!eTeX_mode: 0..1; {identifies compatibility and extended mode}
+@!etex_p: boolean; {was the -etex option specified}
@z
-@x [1360]
-@ @<Incorporate a whatsit node into an hbox@>=do_nothing
+@x [53a.1391] l.??? texarray
+@!eof_seen : array[1..max_in_open] of boolean; {has eof been seen?}
@y
-@ @<Incorporate a whatsit node into an hbox@>=
-if (subtype(p) = pdf_refxform_node) or (subtype(p) = pdf_refximage_node) then
-begin x:=x+pdf_width(p);
-s:=0;
-if pdf_height(p)-s>h then h:=pdf_height(p)-s;
-if pdf_depth(p)+s>d then d:=pdf_depth(p)+s;
-end
+@!eof_seen : ^boolean; {has eof been seen?}
@z
-@x [1361]
-@ @<Let |d| be the width of the whatsit |p|@>=d:=0
+@x [53a.1506] l.??? texarray
+@!grp_stack : array[0..max_in_open] of save_pointer; {initial |cur_boundary|}
+@!if_stack : array[0..max_in_open] of pointer; {initial |cond_ptr|}
@y
-@ @<Let |d| be the width of the whatsit |p|@>=
-if (subtype(p) = pdf_refxform_node) or (subtype(p) = pdf_refximage_node) then
- d := pdf_width(p)
-else
- d := 0
+@!grp_stack : ^save_pointer; {initial |cur_boundary|}
+@!if_stack : ^pointer; {initial |cond_ptr|}
@z
-@x [1362]
-@<Advance \(p)past a whatsit node in the \(l)|line_break| loop@>=@+
-adv_past(cur_p)
+@x [53a.1587] l.??? texarray
+hyph_root:=0; hyph_start:=0;
@y
-@<Advance \(p)past a whatsit node in the \(l)|line_break| loop@>=@+
-begin
-adv_past(cur_p);
-if (subtype(cur_p) = pdf_refxform_node) or (subtype(cur_p) = pdf_refximage_node) then
- act_width:=act_width+pdf_width(cur_p);
-end
@z
-@x [1364]
-@ @<Prepare to move whatsit |p| to the current page, then |goto contribute|@>=
-goto contribute
-@y
-@ @<Prepare to move whatsit |p| to the current page, then |goto contribute|@>=
-begin
- if (subtype(p) = pdf_refxform_node) or (subtype(p) = pdf_refximage_node) then
- begin page_total:=page_total+page_depth+pdf_height(p);
- page_depth:=pdf_depth(p);
- end;
- goto contribute;
-end
-@z
+@x [54/web2c.???] l.??? needed earlier
+replacement, but always existing character |font_bc[f]|.
+@^inner loop@>
-@x [1365]
-@ @<Process whatsit |p| in |vert_break| loop, |goto not_found|@>=
-goto not_found
+@<Declare additional functions for ML\TeX@>=
+function effective_char(@!err_p:boolean;
@y
-@ @<Process whatsit |p| in |vert_break| loop, |goto not_found|@>=
-begin
- if (subtype(p) = pdf_refxform_node) or (subtype(p) = pdf_refximage_node) then
- begin cur_height:=cur_height+prev_dp+pdf_height(p); prev_dp:=pdf_depth(p);
- end;
- goto not_found;
-end
-@z
+replacement, but always existing character |font_bc[f]|.
+@^inner loop@>
-@x [1375]
-@<Implement \.{\\immediate}@>=
-begin get_x_token;
-if (cur_cmd=extension)and(cur_chr<=close_node) then
- begin p:=tail; do_extension; {append a whatsit node}
- out_what(tail); {do the action immediately}
- flush_node_list(tail); tail:=p; link(p):=null;
- end
-else back_input;
-end
-@y
-@<Implement \.{\\immediate}@>=
-begin get_x_token;
-if cur_cmd=extension then begin
- if cur_chr<=close_node then
- begin p:=tail; do_extension; {append a whatsit node}
- out_what(tail); {do the action immediately}
- flush_node_list(tail); tail:=p; link(p):=null;
- end
- else case cur_chr of
- pdf_obj_code: begin
- do_extension; {scan object and set |pdf_last_obj|}
- if obj_data_ptr(pdf_last_obj) = 0 then {this object has not been initialized yet}
- pdf_error("ext1", "`\pdfobj reserveobjnum' cannot be used with \immediate");
- pdf_write_obj(pdf_last_obj);
- end;
- pdf_xform_code: begin
- do_extension; {scan form and set |pdf_last_xform|}
- pdf_cur_form := pdf_last_xform;
- pdf_ship_out(obj_xform_box(pdf_last_xform), false);
- end;
- pdf_ximage_code: begin
- do_extension; {scan image and set |pdf_last_ximage|}
- pdf_write_image(pdf_last_ximage);
- end;
- othercases back_input
- endcases;
-end
-else
- back_input;
-end
+@<Declare \eTeX\ procedures for sc...@>=
+function effective_char(@!err_p:boolean;
@z
-@x [1378]
-@ @<Finish the extensions@>=
-for k:=0 to 15 do if write_open[k] then a_close(write_file[k])
-@y
-@ @<Finish the extensions@>=
-for k:=0 to 15 do if write_open[k] then a_close(write_file[k])
-
-@ Shipping out PDF marks.
-
-@<Types...@>=
-dest_name_entry = record
- objname: str_number; {destination name}
- objnum: integer; {destination object number}
-end;
-
-@ @<Glob...@>=
-@!cur_page_width: scaled; {width of page being shipped}
-@!cur_page_height: scaled; {height of page being shipped}
-@!cur_h_offset: scaled; {horizontal offset of page being shipped}
-@!cur_v_offset: scaled; {vertical offset of page being shipped}
-@!pdf_obj_list: pointer; {list of objects in the current page}
-@!pdf_xform_list: pointer; {list of forms in the current page}
-@!pdf_ximage_list: pointer; {list of images in the current page}
-@!pdf_link_level: integer; {depth of nesting of box containing link annotation}
-@!last_link: pointer; {pointer to the last link annotation}
-@!pdf_link_ht, pdf_link_dp, pdf_link_wd: scaled; {dimensions of the last link
-annotation}
-@!last_thread: pointer; {pointer to the last thread}
-@!pdf_thread_ht, pdf_thread_dp, pdf_thread_wd: scaled; {dimensions of the last
-thread}
-@!pdf_last_thread_id: halfword; {identifier of the last thread}
-@!pdf_last_thread_named_id: boolean; {is identifier of the last thread named}
-@!pdf_thread_level: integer; {depth of nesting of box containing the last thread}
-@!pdf_annot_list: pointer; {list of annotations in the current page}
-@!pdf_link_list: pointer; {list of link annotations in the current page}
-@!pdf_dest_list: pointer; {list of destinations in the current page}
-@!pdf_bead_list: pointer; {list of thread beads in the current page}
-@!pdf_obj_count: integer; {counter of objects}
-@!pdf_xform_count: integer; {counter of forms}
-@!pdf_ximage_count: integer; {counter of images}
-@!pdf_cur_form: integer; {the form being output}
-@!pdf_first_outline, pdf_last_outline, pdf_parent_outline: integer;
-@!pdf_xform_width,
-@!pdf_xform_height,
-@!pdf_xform_depth: scaled; {dimension of the current form}
-@!pdf_info_toks: pointer; {additional keys of Info dictionary}
-@!pdf_catalog_toks: pointer; {additional keys of Catalog dictionary}
-@!pdf_catalog_openaction: integer;
-@!pdf_names_toks: pointer; {additional keys of Names dictionary}
-@!pdf_dest_names_ptr: integer; {first unused position in |dest_names|}
-@!dest_names_size: integer; {maximum number of names in name tree of PDF output file}
-@!dest_names: ^dest_name_entry;
-@!image_orig_x, image_orig_y: integer; {origin of cropped pdf images}
-@!link_level_stack: pointer; {stack to save |pdf_link_level|}
-@!pdf_trailer_toks: pointer; {additional keys of Trailer dictionary}
-
-@ @<Set init...@>=
-pdf_link_level := -1;
-link_level_stack := null;
-pdf_first_outline:= 0;
-pdf_last_outline:= 0;
-pdf_parent_outline:= 0;
-pdf_obj_count := 0;
-pdf_xform_count := 0;
-pdf_ximage_count := 0;
-pdf_dest_names_ptr := 0;
-pdf_info_toks := null;
-pdf_catalog_toks := null;
-pdf_names_toks := null;
-pdf_catalog_openaction := 0;
-pdf_trailer_toks := null;
-
-@ The following procedures are needed for outputing whatsit nodes for
-pdfTeX.
-
-@<Declare procedures needed in |pdf_hlist_out|, |pdf_vlist_out|@>=
-procedure write_action(p: pointer); {write an action specification}
-var s: str_number;
- d: integer;
-begin
- if pdf_action_type(p) = pdf_action_user then begin
- pdf_print_toks_ln(pdf_action_user_tokens(p));
- return;
- end;
- pdf_print("<< ");
- if pdf_action_file(p) <> null then begin
- pdf_print("/F ");
- s := tokens_to_string(pdf_action_file(p));
- if (str_pool[str_start[s]] = 40) and
- (str_pool[str_start[s] + length(s) - 1] = 41) then
- pdf_print(s)
- else begin
- pdf_print_str(s);
- end;
- flush_str(s);
- pdf_print(" ");
- if pdf_action_new_window(p) > 0 then begin
- pdf_print("/NewWindow ");
- if pdf_action_new_window(p) = 1 then
- pdf_print("true ")
- else
- pdf_print("false ");
- end;
- end;
- case pdf_action_type(p) of
- pdf_action_page: begin
- if pdf_action_file(p) = null then begin
- pdf_print("/S /GoTo /D [");
- pdf_print_int(get_obj(obj_type_page, pdf_action_id(p), false));
- pdf_print(" 0 R");
- end
- else begin
- pdf_print("/S /GoToR /D [");
- pdf_print_int(pdf_action_id(p) - 1);
- end;
- pdf_out(" ");
- pdf_print(tokens_to_string(pdf_action_page_tokens(p)));
- flush_str(last_tokens_string);
- pdf_out("]");
- end;
- pdf_action_goto: begin
- if pdf_action_file(p) = null then begin
- pdf_print("/S /GoTo ");
- d := get_obj(obj_type_dest, pdf_action_id(p),
- pdf_action_named_id(p));
- end
- else
- pdf_print("/S /GoToR ");
- if pdf_action_named_id(p) > 0 then begin
- pdf_str_entry("D", tokens_to_string(pdf_action_id(p)));
- flush_str(last_tokens_string);
- end
- else if pdf_action_file(p) = null then
- pdf_indirect("D", d)
- else
- pdf_error("ext4", "`goto' option cannot be used with both `file' and `num'");
- end;
- pdf_action_thread: begin
- pdf_print("/S /Thread ");
- if pdf_action_file(p) = null then
- d := get_obj(obj_type_thread, pdf_action_id(p),
- pdf_action_named_id(p));
- if pdf_action_named_id(p) > 0 then begin
- pdf_str_entry("D", tokens_to_string(pdf_action_id(p)));
- flush_str(last_tokens_string);
- end
- else if pdf_action_file(p) = null then
- pdf_indirect("D", d)
- else
- pdf_int_entry("D", pdf_action_id(p));
- end;
- endcases;
- pdf_print_ln(" >>");
-end;
-
-procedure set_rect_dimens(p, parent_box: pointer; x, y, w, h, d, margin: scaled);
-begin
- pdf_left(p) := cur_h;
- if is_running(w) then
- pdf_right(p) := x + width(parent_box)
- else
- pdf_right(p) := cur_h + w;
- if is_running(h) then
- pdf_top(p) := y - height(parent_box)
- else
- pdf_top(p) := cur_v - h;
- if is_running(d) then
- pdf_bottom(p) := y + depth(parent_box)
- else
- pdf_bottom(p) := cur_v + d;
- pdf_left(p) := pdf_left(p) - margin;
- pdf_top(p) := pdf_top(p) - margin;
- pdf_right(p) := pdf_right(p) + margin;
- pdf_bottom(p) := pdf_bottom(p) + margin;
-end;
-
-procedure do_annot(p, parent_box: pointer; x, y: scaled);
-begin
- if not is_shipping_page then
- pdf_error("ext4", "annotations cannot be inside an XForm");
- if doing_leaders then
- return;
- set_rect_dimens(p, parent_box, x, y,
- pdf_width(p), pdf_height(p), pdf_depth(p), 0);
- obj_annot_ptr(pdf_annot_objnum(p)) := p;
- pdf_append_list(pdf_annot_objnum(p))(pdf_annot_list);
-end;
-
-@ To implement nesting link annotations, we need a stack to save box testing
-level of each link that has been broken. Each stack entry holds the
-box nesting level and pointer the whatsit node created for
-corresponding \.{\\pdfstartlink}.
-
-@d link_level(#) == info(#)
-@d link_ptr(#) == info(# + 1)
-
-@<Declare procedures needed in |pdf_hlist_out|, |pdf_vlist_out|@>=
-procedure save_link_level(l: pointer);
-var p, r: pointer;
-begin
- pdf_link_level := cur_s;
- r := copy_node_list(l);
- pdf_link_wd := pdf_width(r);
- pdf_link_ht := pdf_height(r);
- pdf_link_dp := pdf_depth(r);
- p := get_node(small_node_size);
- link_level(p) := pdf_link_level;
- link_ptr(p) := r;
- link(p) := link_level_stack;
- link_level_stack := p;
-end;
-
-procedure do_link(p, parent_box: pointer; x, y: scaled);
-begin
- if not is_shipping_page then
- pdf_error("ext4", "link annotations cannot be inside an XForm");
- if type(parent_box) <> hlist_node then
- pdf_error("ext4", "link annotations can be inside hbox only");
- save_link_level(p);
- set_rect_dimens(p, parent_box, x, y,
- pdf_link_wd, pdf_link_ht, pdf_link_dp, pdf_link_margin);
- last_link := p;
- pdf_create_obj(obj_type_others, 0);
- obj_annot_ptr(obj_ptr) := p;
- pdf_append_list(obj_ptr)(pdf_link_list);
-end;
-
-procedure restore_link_level;
-var p, r: pointer;
-begin
- if link_level_stack = null then
- pdf_error("ext4", "invalid stack of link nesting level");
- p := link_level_stack;
- link_level_stack := link(p);
- r := link_ptr(p);
- flush_node_list(r);
- free_node(p, small_node_size);
- p := link_level_stack;
- if p = null then
- pdf_link_level := -1
- else begin
- pdf_link_level := link_level(p);
- r := link_ptr(p);
- pdf_link_wd := pdf_width(r);
- pdf_link_ht := pdf_height(r);
- pdf_link_dp := pdf_depth(r);
- end;
-end;
-
-procedure end_link;
-begin
- if pdf_link_level <> cur_s then
- pdf_error("ext4", "\pdfendlink ended up in different nesting level than \pdfstartlink");
- if is_running(pdf_link_wd) and (last_link <> null) then
- pdf_right(last_link) := cur_h + pdf_link_margin;
- restore_link_level;
- last_link := null;
-end;
-
-@ For ``running'' annotations we must append a new node when the end of
-annotation is in other box than its start. The new created node is identical to
-corresponding whatsit node representing the start of annotation, but its
-|info| field is |null|. We set |info| field just before destroying the node, in
-order to use |flush_node_list| to do the job.
-
-@<Declare procedures needed in |pdf_hlist_out|, |pdf_vlist_out|@>=
-procedure append_link(parent_box: pointer; x, y: scaled); {append a new
-|pdf_start_link_node| to |pdf_link_list| and update |last_link|}
-var p, r: integer;
-begin
- if type(parent_box) <> hlist_node then
- pdf_error("ext4", "link annotations can be inside hbox only");
- r := copy_node_list(link_ptr(link_level_stack)); {copy link node to |r|}
- info(r) := max_halfword; {mark that this node is not a whatsit node}
- link(r) := null; {this node will be destroyed separately}
- set_rect_dimens(r, parent_box, x, y,
- pdf_link_wd, pdf_link_ht, pdf_link_dp, pdf_link_margin);
- pdf_create_obj(obj_type_others, 0);
- obj_annot_ptr(obj_ptr) := r;
- last_link := r;
- pdf_append_list(obj_ptr)(pdf_link_list);
-end;
-
-@ Threads are handled in similar way as link annotations.
-
-@<Declare procedures needed in |pdf_hlist_out|, |pdf_vlist_out|@>=
-procedure append_bead(p: pointer);
-var a, b, c, t: integer;
-begin
- if not is_shipping_page then
- pdf_error("ext4", "threads cannot be inside an XForm");
- t := get_obj(obj_type_thread, pdf_thread_id(p), pdf_thread_named_id(p));
- b := pdf_new_objnum;
- obj_bead_ptr(b) := pdf_get_mem(pdfmem_bead_size);
- obj_bead_page(b) := pdf_last_page;
- obj_bead_data(b) := p;
- if pdf_thread_attr(p) <> null then
- obj_bead_attr(b) := tokens_to_string(pdf_thread_attr(p))
- else
- obj_bead_attr(b) := 0;
- if obj_thread_first(t) = 0 then begin
- obj_thread_first(t) := b;
- obj_bead_next(b) := b;
- obj_bead_prev(b) := b;
- end
- else begin
- a := obj_thread_first(t);
- c := obj_bead_prev(a);
- obj_bead_prev(b) := c;
- obj_bead_next(b) := a;
- obj_bead_prev(a) := b;
- obj_bead_next(c) := b;
- end;
- pdf_append_list(b)(pdf_bead_list);
-end;
-
-procedure do_thread(p, parent_box: pointer; x, y: scaled);
-begin
- if doing_leaders then
- return;
- if subtype(p) = pdf_start_thread_node then begin
- pdf_thread_wd := pdf_width(p);
- pdf_thread_ht := pdf_height(p);
- pdf_thread_dp := pdf_depth(p);
- pdf_last_thread_id := pdf_thread_id(p);
- pdf_last_thread_named_id := (pdf_thread_named_id(p) > 0);
- if pdf_last_thread_named_id then
- add_token_ref(pdf_thread_id(p));
- pdf_thread_level := cur_s;
- end;
- set_rect_dimens(p, parent_box, x, y,
- pdf_width(p), pdf_height(p), pdf_depth(p),
- pdf_thread_margin);
- append_bead(p);
- last_thread := p;
-end;
-
-procedure append_thread(parent_box: pointer; x, y: scaled);
-var p: pointer;
-begin
- p := get_node(pdf_thread_node_size);
- info(p) := max_halfword; {this is not a whatsit node}
- link(p) := null; {this node will be destroyed separately}
- pdf_width(p) := pdf_thread_wd;
- pdf_height(p) := pdf_thread_ht;
- pdf_depth(p) := pdf_thread_dp;
- pdf_thread_attr(p) := null;
- pdf_thread_id(p) := pdf_last_thread_id;
- if pdf_last_thread_named_id then begin
- add_token_ref(pdf_thread_id(p));
- pdf_thread_named_id(p) := 1;
- end
- else
- pdf_thread_named_id(p) := 0;
- set_rect_dimens(p, parent_box, x, y,
- pdf_width(p), pdf_height(p), pdf_depth(p),
- pdf_thread_margin);
- append_bead(p);
- last_thread := p;
-end;
-
-procedure end_thread;
-begin
- if pdf_thread_level <> cur_s then
- pdf_error("ext4", "\pdfendthread ended up in different nesting level than \pdfstartthread");
- if is_running(pdf_thread_dp) and (last_thread <> null) then
- pdf_bottom(last_thread) := cur_v + pdf_thread_margin;
- if pdf_last_thread_named_id then
- delete_token_ref(pdf_last_thread_id);
- last_thread := null;
-end;
-
-function open_subentries(p: pointer): integer;
-var k, c: integer;
- l, r: integer;
-begin
- k := 0;
- if obj_outline_first(p) <> 0 then begin
- l := obj_outline_first(p);
- repeat
- incr(k);
- c := open_subentries(l);
- if obj_outline_count(l) > 0 then
- k := k + c;
- obj_outline_parent(l) := p;
- r := obj_outline_next(l);
- if r = 0 then
- obj_outline_last(p) := l;
- l := r;
- until l = 0;
- end;
- if obj_outline_count(p) > 0 then
- obj_outline_count(p) := k
- else
- obj_outline_count(p) := -k;
- open_subentries := k;
-end;
-
-procedure do_dest(p, parent_box: pointer; x, y: scaled);
-var k: integer;
-begin
- if not is_shipping_page then
- pdf_error("ext4", "destinations cannot be inside an XForm");
- if doing_leaders then
- return;
- k := get_obj(obj_type_dest, pdf_dest_id(p), pdf_dest_named_id(p));
- if obj_dest_ptr(k) <> null then begin
- warn_dest_dup(pdf_dest_id(p), pdf_dest_named_id(p),
- "ext4", "has been already used, duplicate ignored");
- return;
- end;
- obj_dest_ptr(k) := p;
- pdf_append_list(k)(pdf_dest_list);
- case pdf_dest_type(p) of
- pdf_dest_xyz: begin
- pdf_left(p) := cur_h;
- pdf_top(p) := cur_v;
- end;
- pdf_dest_fith,
- pdf_dest_fitbh:
- pdf_top(p) := cur_v;
- pdf_dest_fitv,
- pdf_dest_fitbv:
- pdf_left(p) := cur_h;
- pdf_dest_fit,
- pdf_dest_fitb:
- do_nothing;
- pdf_dest_fitr:
- set_rect_dimens(p, parent_box, x, y,
- pdf_width(p), pdf_height(p), pdf_depth(p),
- pdf_dest_margin);
- endcases;
-end;
-
-procedure out_form(p: pointer);
-begin
- pdf_end_text;
- pdf_print_ln("q");
- if pdf_lookup_list(pdf_xform_list, pdf_xform_objnum(p)) = null then
- pdf_append_list(pdf_xform_objnum(p))(pdf_xform_list);
- cur_v := cur_v + obj_xform_depth(pdf_xform_objnum(p));
- pdf_print("1 0 0 1 ");
- pdf_print_bp(pdf_x(cur_h)); pdf_out(" ");
- pdf_print_bp(pdf_y(cur_v));
- pdf_print_ln(" cm");
- pdf_print("/Fm");
- pdf_print_int(obj_info(pdf_xform_objnum(p)));
- pdf_print_resname_prefix;
- pdf_print_ln(" Do");
- pdf_print_ln("Q");
-end;
-
-procedure out_image(p: pointer);
-var image: integer;
-begin
- image := obj_ximage_data(pdf_ximage_objnum(p));
- pdf_end_text;
- pdf_print_ln("q");
- if pdf_lookup_list(pdf_ximage_list, pdf_ximage_objnum(p)) = null then
- pdf_append_list(pdf_ximage_objnum(p))(pdf_ximage_list);
- if not is_pdf_image(image) then begin
- pdf_print_real(ext_xn_over_d(pdf_width(p),
- ten_pow[6], one_hundred_bp), 4);
- pdf_print(" 0 0 ");
- pdf_print_real(ext_xn_over_d(pdf_height(p) + pdf_depth(p),
- ten_pow[6], one_hundred_bp), 4);
- pdf_out(" ");
- pdf_print_bp(pdf_x(cur_h)); pdf_out(" ");
- pdf_print_bp(pdf_y(cur_v));
- end
- else begin
- pdf_print_real(ext_xn_over_d(pdf_width(p),
- ten_pow[6], image_width(image)), 6);
- pdf_print(" 0 0 ");
- pdf_print_real(ext_xn_over_d(pdf_height(p) + pdf_depth(p),
- ten_pow[6], image_height(image)), 6);
- pdf_out(" ");
- pdf_print_bp(pdf_x(cur_h) -
- ext_xn_over_d(pdf_width(p), epdf_orig_x(image),
- image_width(image)));
- pdf_out(" ");
- pdf_print_bp(pdf_y(cur_v) -
- ext_xn_over_d(pdf_height(p), epdf_orig_y(image),
- image_height(image)));
- end;
- pdf_print_ln(" cm");
- pdf_print("/Im");
- pdf_print_int(obj_info(pdf_ximage_objnum(p)));
- pdf_print_resname_prefix;
- pdf_print_ln(" Do");
- pdf_print_ln("Q");
-end;
-
-
-@ @<Output the whatsit node |p| in |pdf_vlist_out|@>=
-case subtype(p) of
-pdf_literal_node:
- pdf_out_literal(p);
-pdf_refobj_node:
- pdf_append_list(pdf_obj_objnum(p))(pdf_obj_list);
-pdf_refxform_node:
- @<Output a Form node in a vlist@>;
-pdf_refximage_node:
- @<Output a Image node in a vlist@>;
-pdf_annot_node:
- do_annot(p, this_box, left_edge, top_edge + height(this_box));
-pdf_start_link_node:
- pdf_error("ext4", "\pdfstartlink ended up in vlist");
-pdf_end_link_node:
- pdf_error("ext4", "\pdfendlink ended up in vlist");
-pdf_dest_node:
- do_dest(p, this_box, left_edge, top_edge + height(this_box));
-pdf_thread_node,
-pdf_start_thread_node:
- do_thread(p, this_box, left_edge, top_edge + height(this_box));
-pdf_end_thread_node:
- end_thread;
-pdf_save_pos_node:
- @<Save current position to |pdf_last_x_pos|, |pdf_last_y_pos|@>;
-special_node:
- pdf_special(p);
-othercases out_what(p);
-endcases
-
-@ @<Glob...@>=
-@!is_shipping_page: boolean; {set to |shipping_page| when |pdf_ship_out| starts}
-
-@ @<Save current position to |pdf_last_x_pos|, |pdf_last_y_pos|@>=
-begin
- pdf_last_x_pos := cur_h;
- if is_shipping_page then
- pdf_last_y_pos := cur_page_height - cur_v
- else
- pdf_last_y_pos := pdf_xform_height + pdf_xform_depth - cur_v;
-end
-
-@ @<Output a Image node in a vlist@>=
-begin cur_v:=cur_v+pdf_height(p)+pdf_depth(p); save_v:=cur_v;
- cur_h:=left_edge;
- out_image(p);
- cur_v:=save_v; cur_h:=left_edge;
- end
-
-@ @<Output a Form node in a vlist@>=
-begin cur_v:=cur_v+pdf_height(p); save_v:=cur_v;
- cur_h:=left_edge;
- out_form(p);
- cur_v:=save_v+pdf_depth(p); cur_h:=left_edge;
- end
-
-@ @<Output the whatsit node |p| in |pdf_hlist_out|@>=
-case subtype(p) of
-pdf_literal_node:
- pdf_out_literal(p);
-pdf_refobj_node:
- pdf_append_list(pdf_obj_objnum(p))(pdf_obj_list);
-pdf_refxform_node:
- @<Output a Form node in a hlist@>;
-pdf_refximage_node:
- @<Output a Image node in a hlist@>;
-pdf_annot_node:
- do_annot(p, this_box, left_edge, base_line);
-pdf_start_link_node:
- do_link(p, this_box, left_edge, base_line);
-pdf_end_link_node: begin
- end_link;
- @<Create link annotation for the current hbox if needed@>;
-end;
-pdf_dest_node:
- do_dest(p, this_box, left_edge, base_line);
-pdf_thread_node:
- do_thread(p, this_box, left_edge, base_line);
-pdf_start_thread_node:
- pdf_error("ext4", "\pdfstartthread ended up in hlist");
-pdf_end_thread_node:
- pdf_error("ext4", "\pdfendthread ended up in hlist");
-pdf_save_pos_node:
- @<Save current position to |pdf_last_x_pos|, |pdf_last_y_pos|@>;
-special_node:
- pdf_special(p);
-othercases out_what(p);
-endcases
-
-@ @<Output a Image node in a hlist@>=
-begin
- cur_v:=base_line+pdf_depth(p);
- edge:=cur_h;
- out_image(p);
- cur_h:=edge+pdf_width(p); cur_v:=base_line;
- end
-
-@ @<Output a Form node in a hlist@>=
-begin
- cur_v:=base_line;
- edge:=cur_h;
- out_form(p);
- cur_h:=edge+pdf_width(p); cur_v:=base_line;
- end
-@z