summaryrefslogtreecommitdiff
path: root/Build/source/texk/web2c/pdftexdir/pdftex.web
diff options
context:
space:
mode:
authorMartin Schröder <martin@oneiros.de>2007-07-11 21:13:59 +0000
committerMartin Schröder <martin@oneiros.de>2007-07-11 21:13:59 +0000
commit7bf56e6bfcd7b204b3507dc9acaaaa3dce2cbcdb (patch)
tree5f8b4be4a21dc917441e4d2a1ec3e6fe25fd0192 /Build/source/texk/web2c/pdftexdir/pdftex.web
parentc0da09fd6e4a542610245624c185a66f5ec814b2 (diff)
Imported pdftex 1.40.4
git-svn-id: svn://tug.org/texlive/trunk@4561 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/texk/web2c/pdftexdir/pdftex.web')
-rw-r--r--Build/source/texk/web2c/pdftexdir/pdftex.web853
1 files changed, 526 insertions, 327 deletions
diff --git a/Build/source/texk/web2c/pdftexdir/pdftex.web b/Build/source/texk/web2c/pdftexdir/pdftex.web
index 693a347d447..b005393e757 100644
--- a/Build/source/texk/web2c/pdftexdir/pdftex.web
+++ b/Build/source/texk/web2c/pdftexdir/pdftex.web
@@ -1,4 +1,4 @@
-% Copyright (c) 1996-2006 Han Th\^e\llap{\raise 0.5ex\hbox{\'{}}} Th\`anh, <thanh@@pdftex.org>
+% Copyright (c) 1996-2007 Han Th\^e\llap{\raise 0.5ex\hbox{\'{}}} Th\`anh, <thanh@@pdftex.org>
% This file is part of pdfTeX.
@@ -12,8 +12,8 @@
% A PARTICULAR PURPOSE. See the GNU General Public License for more details.
% You should have received a copy of the GNU General Public License along with
-% pdfTeX; if not, write to the Free Software Foundation, Inc., 59 Temple Place,
-% Suite 330, Boston, MA 02111-1307 USA
+% pdfTeX; if not, write to the Free Software Foundation, Inc., 51 Franklin
+% Street, Fifth Floor, Boston, MA 02110-1301 USA.
% e-TeX is copyright (C) 1994,98 by Peter Breitenlohner; all rights are
% reserved. Copying of this file is authorized only if (1) you are Peter
@@ -286,8 +286,8 @@ known as `\eTeX'.
{printed when \eTeX\ starts}
@#
@d pdftex_version==140 { \.{\\pdftexversion} }
-@d pdftex_revision=="3" { \.{\\pdftexrevision} }
-@d pdftex_version_string=='-1.40.3' {current \pdfTeX\ version}
+@d pdftex_revision=="4" { \.{\\pdftexrevision} }
+@d pdftex_version_string=='-1.40.4' {current \pdfTeX\ version}
@#
@d pdfeTeX_banner=='This is pdfeTeX, Version 3.141592',pdftex_version_string,eTeX_version_string
{printed when \pdfeTeX\ starts}
@@ -4781,7 +4781,8 @@ that might be expanded by `\.{\\the}'.
@d hyph_data=99 {hyphenation data ( \.{\\hyphenation}, \.{\\patterns} )}
@d set_interaction=100 {define level of interaction ( \.{\\batchmode}, etc.~)}
@d letterspace_font=101 {letterspace a font ( \.{\\letterspacefont} )}
-@d max_command=101 {the largest command code seen at |big_switch|}
+@d pdf_copy_font=102 {create a new font instance ( \.{\\pdfcopyfont} )}
+@d max_command=102 {the largest command code seen at |big_switch|}
@ The remaining command codes are extra special, since they cannot get through
\TeX's scanner to the main control routine. They have been given values higher
@@ -4919,7 +4920,7 @@ level is kept in the global quantities |mode|, |head|, |tail|, |prev_graf|,
|aux|, and |mode_line|, which live in a \PASCAL\ record that is ready to
be pushed onto |nest| if necessary.
-@d ignore_depth==-65536000 {|prev_depth| value that is ignored}
+@d ignore_depth==-65536000 {magic dimension value to mean `ignore me'}
@<Types...@>=
@!list_state_record=record@!mode_field:-mmode..mmode;@+
@@ -5033,7 +5034,7 @@ end;
@ @<Show the auxiliary...@>=
case abs(m) div (max_command+1) of
0: begin print_nl("prevdepth ");
- if a.sc<=ignore_depth then print("ignored")
+ if a.sc<=pdf_ignored_dimen then print("ignored")
else print_scaled(a.sc);
if nest[p].pg_field<>0 then
begin print(", prevgraf ");
@@ -5658,7 +5659,8 @@ that will be defined later.
@d pdf_append_kern_code = pdftex_first_integer_code + 23 {append kern before certain characters?}
@d pdf_gen_tounicode_code = pdftex_first_integer_code + 24 {generate ToUnicode for fonts?}
@d pdf_draftmode_code = pdftex_first_integer_code + 25 {switch on draftmode if positive}
-@d pdf_int_pars=pdftex_first_integer_code + 26 {total number of \pdfTeX's integer parameters}
+@d pdf_inclusion_copy_font_code = pdftex_first_integer_code + 26 {generate ToUnicode for fonts?}
+@d pdf_int_pars=pdftex_first_integer_code + 27 {total number of \pdfTeX's integer parameters}
@#
@d etex_int_base=pdf_int_pars {base for \eTeX's integer parameters}
@d tracing_assigns_code=etex_int_base {show assignments}
@@ -5763,6 +5765,7 @@ that will be defined later.
@d pdf_image_hicolor == int_par(pdf_image_hicolor_code)
@d pdf_image_apply_gamma == int_par(pdf_image_apply_gamma_code)
@d pdf_draftmode == int_par(pdf_draftmode_code)
+@d pdf_inclusion_copy_font == int_par(pdf_inclusion_copy_font_code)
@#
@d tracing_assigns==int_par(tracing_assigns_code)
@d tracing_groups==int_par(tracing_groups_code)
@@ -5864,6 +5867,7 @@ pdf_prepend_kern_code: print_esc("pdfprependkern");
pdf_append_kern_code: print_esc("pdfappendkern");
pdf_gen_tounicode_code: print_esc("pdfgentounicode");
pdf_draftmode_code: print_esc("pdfdraftmode");
+pdf_inclusion_copy_font_code: print_esc("pdfinclusioncopyfonts");
@/@<Cases for |print_param|@>@/
othercases print("[unknown integer parameter!]")
endcases;
@@ -6039,6 +6043,8 @@ primitive("pdfgentounicode",assign_int,int_base+pdf_gen_tounicode_code);@/
@!@:pdf_gen_tounicode_}{\.{\\pdfgentounicode} primitive@>
primitive("pdfdraftmode",assign_int,int_base+pdf_draftmode_code);@/
@!@:pdf_draftmode_}{\.{\\pdfdraftmode} primitive@>
+primitive("pdfinclusioncopyfonts",assign_int,int_base+pdf_inclusion_copy_font_code);@/
+@!@:pdf_inclusion_copy_font_}{\.{\\pdfinclusioncopyfonts} primitive@>
@ @<Cases of |print_cmd_chr|...@>=
assign_int: if chr_code<count_base then print_param(chr_code-int_base)
@@ -6146,8 +6152,9 @@ here, and the 256 \.{\\dimen} registers.
@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 pdf_px_dimen_code = pdftex_first_dimen_code + 11
-@d pdftex_last_dimen_code = pdftex_first_dimen_code + 11 {last number defined in this section}
+@d pdf_ignored_dimen_code = pdftex_first_dimen_code + 11
+@d pdf_px_dimen_code = pdftex_first_dimen_code + 12
+@d pdftex_last_dimen_code = pdftex_first_dimen_code + 12 {last number defined in this section}
@d dimen_pars = pdftex_last_dimen_code + 1 {total number of dimension parameters}
@d scaled_base=dimen_base+dimen_pars
{table of 256 user-defined \.{\\dimen} registers}
@@ -6187,6 +6194,7 @@ here, and the 256 \.{\\dimen} registers.
@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)
+@d pdf_ignored_dimen == dimen_par(pdf_ignored_dimen_code)
@d pdf_px_dimen == dimen_par(pdf_px_dimen_code)
@p procedure print_length_param(@!n:integer);
@@ -6223,6 +6231,7 @@ 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");
+pdf_ignored_dimen_code: print_esc("pdfignoreddimen");
pdf_px_dimen_code: print_esc("pdfpxdimen");
othercases print("[unknown dimen parameter!]")
endcases;
@@ -6295,6 +6304,8 @@ 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@>
+primitive("pdfignoreddimen",assign_dimen,dimen_base+pdf_ignored_dimen_code);@/
+@!@:pdf_ignored_dimen_}{\.{\\pdfignoreddimen} primitive@>
primitive("pdfpxdimen",assign_dimen,dimen_base+pdf_px_dimen_code);@/
@!@:pdf_px_dimen_}{\.{\\pdfpxdimen} primitive@>
@@ -6662,6 +6673,8 @@ primitive("font",def_font,0);@/
@!@:font_}{\.{\\font} primitive@>
primitive("letterspacefont",letterspace_font,0);@/
@!@:letterspace_font_}{\.{\\letterspacefont} primitive@>
+primitive("pdfcopyfont",pdf_copy_font,0);@/
+@!@:pdf_copy_font_}{\.{\\pdfcopyfont} primitive@>
primitive("fontdimen",assign_font_dimen,0);@/
@!@:font_dimen_}{\.{\\fontdimen} primitive@>
primitive("halign",halign,0);@/
@@ -6740,6 +6753,7 @@ char_num: print_esc("char");
cs_name: print_esc("csname");
def_font: print_esc("font");
letterspace_font: print_esc("letterspacefont");
+pdf_copy_font: print_esc("pdfcopyfont");
delim_num: print_esc("delimiter");
divide: print_esc("divide");
end_cs_name: print_esc("endcsname");
@@ -8856,8 +8870,9 @@ if cur_cs < hash_base then
else
cur_cs := prim_lookup(text(cur_cs));
if cur_cs<>undefined_primitive then begin
- if cur_cmd>max_command then begin
- cur_cmd := prim_eq_type(cur_cs);
+ t := prim_eq_type(cur_cs);
+ if t>max_command then begin
+ cur_cmd := t;
cur_chr := prim_equiv(cur_cs);
cur_tok := (cur_cmd*@'400)+cur_chr;
cur_cs := 0;
@@ -9524,7 +9539,7 @@ var m:halfword; {|chr_code| part of the operand token}
begin m:=cur_chr;
case cur_cmd of
def_code: @<Fetch a character code from some table@>;
-toks_register,assign_toks,def_family,set_font,def_font,letterspace_font: @<Fetch a token list or
+toks_register,assign_toks,def_family,set_font,def_font,letterspace_font,pdf_copy_font: @<Fetch a token list or
font identifier, provided that |level=tok_val|@>;
assign_int: scanned_result(eqtb[m].int)(int_val);
assign_dimen: scanned_result(eqtb[m].sc)(dimen_val);
@@ -10333,7 +10348,7 @@ if mag<>1000 then
end
@ The necessary conversion factors can all be specified exactly as
-fractions whose numerator and denominator are 65535 or less.
+fractions whose numerator and denominator add to 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@>
@@ -10341,7 +10356,13 @@ 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$.
+The new Cicero follows the new Didot point; $\rm 1\,nc=12\,nd$.
+These would lead to the ratios $21681/20320$ and $65043/5080$,
+respectively.
+The closest approximations supported by the algorithm would be
+$11183/10481$ and $1370/107$. In order to maintain the
+relation $\rm 1\,nc=12\,nd$, we pick the ratio $685/642$ for
+$\rm nd$, however.
@d set_conversion_end(#)== denom:=#; end
@d set_conversion(#)==@+begin num:=#; set_conversion_end
@@ -10361,9 +10382,9 @@ else if scan_keyword("dd") then set_conversion(1238)(1157)
@.dd@>
else if scan_keyword("cc") then set_conversion(14856)(1157)
@.cc@>
-else if scan_keyword("nd") then set_conversion(21681)(20320)
+else if scan_keyword("nd") then set_conversion(685)(642)
@.nd@>
-else if scan_keyword("nc") then set_conversion(65043)(5080)
+else if scan_keyword("nc") then set_conversion(1370)(107)
@.nc@>
else if scan_keyword("sp") then goto done
@.sp@>
@@ -10756,7 +10777,7 @@ pdf_font_name_code, pdf_font_objnum_code, pdf_font_size_code: begin
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);
+ pdf_check_vf_cur_val;
if not font_used[cur_val] then
pdf_init_font_cur_val;
end;
@@ -13176,7 +13197,7 @@ procedure scan_font_ident;
var f:internal_font_number;
@!m:halfword;
begin @<Get the next non-blank non-call...@>;
-if (cur_cmd=def_font) or (cur_cmd=letterspace_font) then f:=cur_font
+if (cur_cmd=def_font) or (cur_cmd=letterspace_font) or (cur_cmd=pdf_copy_font) then f:=cur_font
else if cur_cmd=set_font then f:=cur_chr
else if cur_cmd=def_family then
begin m:=cur_chr; scan_four_bit_int; f:=equiv(m+cur_val);
@@ -15149,6 +15170,7 @@ begin
fixed_image_apply_gamma := fix_int(pdf_image_apply_gamma, 0, 1);
fixed_pdf_objcompresslevel := fix_int(pdf_objcompresslevel, 0, 3);
fixed_pdf_draftmode := fix_int(pdf_draftmode, 0, 1);
+ fixed_inclusion_copy_font := fix_int(pdf_inclusion_copy_font, 0, 1);
if (fixed_pdf_minor_version >= 5) and (fixed_pdf_objcompresslevel > 0) then
pdf_os_enable := true
else begin
@@ -15304,6 +15326,7 @@ begin
print(": "); print(p);
if append_nl then
print_ln;
+ if history=spotless then history:=warning_issued;
end;
procedure pdf_os_get_os_buf(s: integer); {check that |s| bytes more
@@ -15625,6 +15648,7 @@ DVI}
@!fixed_pk_resolution: integer;
@!fixed_decimal_digits: integer;
@!fixed_gen_tounicode: integer;
+@!fixed_inclusion_copy_font: integer;
@!pk_scale_factor: integer;
@!pdf_output_option: integer;
@!pdf_output_value: integer;
@@ -15989,7 +16013,7 @@ 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 five integer fields and represents an object
+|obj_entry|. Each entry contains five 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.
@@ -16007,10 +16031,9 @@ The second field of |obj_entry| contains link to the next
object in |obj_tab| if this object is linked in a list.
The third field holds the byte offset of the object in the output PDF file,
-or its byte offset within an object stream.
-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.
+or its byte offset within an object stream. As long as the object is not
+written, this field is used for flags about the write status of the object;
+then it has a negative value.
The fourth field holds the object number of the object stream, into which
the object is included.
@@ -16021,10 +16044,14 @@ 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 for this object in PDF output file, or object stream number for this object}
+@d obj_offset(#) == obj_tab[#].int2 {negative (flags), or byte offset for this object in PDF output file, or object stream number for this object}
@d obj_os_idx(#) == obj_tab[#].int3 {index of this object in object stream}
@d obj_aux(#) == obj_tab[#].int4 {auxiliary pointer}
-@d is_obj_written(#) == (obj_offset(#) <> 0)
+
+@d set_obj_fresh(#) == obj_offset(#) := -2
+@d set_obj_scheduled(#) == if obj_offset(#) = -2 then obj_offset(#) := -1
+@d is_obj_scheduled(#) == (obj_offset(#) > -2)
+@d is_obj_written(#) == (obj_offset(#) > -1)
@# {types of objects}
@d obj_type_others == 0 {objects which are not linked in any list}
@@ -16055,7 +16082,7 @@ destination |pdf_left| and |pdf_top| are used for some types of destinations}
@d pdf_right(#) == mem[# + 3].sc
@d pdf_bottom(#) == mem[# + 4].sc
-@# {dimesion of destinations/threads/annotations (in whatsit node)}
+@# {dimension 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
@@ -16089,7 +16116,7 @@ destination |pdf_left| and |pdf_top| are used for some types of destinations}
@d pdf_setmatrix_node_size == 2
@d pdf_setmatrix_data(#) == link(#+1) {data}
-@# {data structure for \.{\\pdsave}}
+@# {data structure for \.{\\pdfsave}}
@d pdf_save_node_size == 2
@# {data structure for \.{\\pdfrestore}}
@@ -16328,7 +16355,7 @@ begin
incr(sys_obj_ptr);
obj_ptr := sys_obj_ptr;
obj_info(obj_ptr) := i;
- obj_offset(obj_ptr) := 0;
+ set_obj_fresh(obj_ptr);
obj_aux(obj_ptr) := 0;
avl_put_obj(obj_ptr, t);
if t = obj_type_page then begin
@@ -16712,28 +16739,15 @@ during adjusting spacing. Such fonts are linked via the |pdf_font_elink| array.
@d virtual_font_type = 1 {virtual font}
@d real_font_type = 2 {real font}
@d subst_font_type = 3 {substituted font}
-@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 for \pdfTeX@>=
-procedure do_vf; forward;
+procedure pdf_check_vf_cur_val; forward;
procedure pdf_init_font_cur_val; 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; {temporary register to pass parameter to some subroutines}
@ Here come some subroutines to deal with expanded fonts for HZ-algorithm.
@@ -16747,6 +16761,8 @@ else if type(#) = ligature_node then begin
f := font(lig_char(#));
end
+@d non_existent_path == "///..."
+
@p
procedure set_tag_code(f: internal_font_number; c: eight_bits; i: integer);
var fixedi:integer;
@@ -17020,7 +17036,10 @@ var k: internal_font_number;
begin
if fs <> 0 then begin
for k := font_base + 1 to font_ptr do
- if str_eq_str(font_name[k], s) and (font_size[k] = fs) then begin
+ if (font_area[k] <> non_existent_path) and
+ str_eq_str(font_name[k], s) and
+ (font_size[k] = fs) then
+ begin
flush_str(s);
tfm_lookup := k;
return;
@@ -17028,7 +17047,9 @@ begin
end
else begin
for k := font_base + 1 to font_ptr do
- if str_eq_str(font_name[k], s) then begin
+ if (font_area[k] <> non_existent_path) and
+ str_eq_str(font_name[k], s) then
+ begin
flush_str(s);
tfm_lookup := k;
return;
@@ -17056,45 +17077,6 @@ begin
load_expand_font := k;
end;
-function auto_expand_vf(f: internal_font_number): boolean;
-{check for a virtual auto-expanded font}
-var save_f, bf, lf: internal_font_number;
- e, k: integer;
-begin
- auto_expand_vf := false;
- if (not pdf_font_auto_expand[f]) or (pdf_font_blink[f] = null_font) then
- return; {not an auto-expanded font}
- bf := pdf_font_blink[f];
- if pdf_font_type[bf] = new_font_type then {we must process the base font first}
- begin
- save_f := tmp_f;
- tmp_f := bf;
- do_vf;
- tmp_f := save_f;
- end;
-
- if pdf_font_type[bf] <> virtual_font_type then
- return; {not a virtual font}
-
- e := pdf_font_expand_ratio[f];
- for k := 0 to vf_local_font_num[bf] - 1 do begin
- lf := vf_default_font[bf] + k;
- allocvffnts;
- {copy vf local font numbers:}
- vf_e_fnts[vf_nf] := vf_e_fnts[lf];
- {definition of local vf fonts are expanded from base fonts:}
- vf_i_fnts[vf_nf] := auto_expand_font(vf_i_fnts[lf], e);
- copy_expand_params(vf_i_fnts[vf_nf], vf_i_fnts[lf], e);
- incr(vf_nf);
- end;
- vf_packet_base[f] := vf_packet_base[bf];
- vf_local_font_num[f] := vf_local_font_num[bf];
- vf_default_font[f] := vf_nf - vf_local_font_num[f];
-
- pdf_font_type[f] := virtual_font_type;
- auto_expand_vf := true;
-end;
-
function fix_expand_value(f: internal_font_number; e: integer): integer;
{return the multiple of |pdf_font_step[f]| that is nearest to |e|}
var step: integer;
@@ -17160,15 +17142,15 @@ begin
end;
procedure set_expand_params(f: internal_font_number; auto_expand: boolean;
- font_stretch, font_shrink, font_step, expand_ratio: integer);
+ stretch_limit, shrink_limit, font_step, expand_ratio: integer);
{expand a font with given parameters}
begin
pdf_font_step[f] := font_step;
pdf_font_auto_expand[f] := auto_expand;
- if font_stretch > 0 then
- pdf_font_stretch[f] := get_expand_font(f, font_stretch);
- if font_shrink > 0 then
- pdf_font_shrink[f] := get_expand_font(f, -font_shrink);
+ if stretch_limit > 0 then
+ pdf_font_stretch[f] := get_expand_font(f, stretch_limit);
+ if shrink_limit > 0 then
+ pdf_font_shrink[f] := get_expand_font(f, -shrink_limit);
if expand_ratio <> 0 then
pdf_font_expand_ratio[f] := expand_ratio;
end;
@@ -17182,7 +17164,7 @@ begin
lf := vf_i_fnts[vf_default_font[f] + k];
set_expand_params(lf, pdf_font_auto_expand[f],
pdf_font_expand_ratio[pdf_font_stretch[f]],
- pdf_font_expand_ratio[pdf_font_shrink[f]],
+ -pdf_font_expand_ratio[pdf_font_shrink[f]],
pdf_font_step[f], pdf_font_expand_ratio[f]);
if pdf_font_type[lf] = virtual_font_type then
vf_expand_local_fonts(lf);
@@ -17190,7 +17172,7 @@ begin
end;
procedure read_expand_font; {read font expansion spec and load expanded font}
-var font_shrink, font_stretch, font_step: integer;
+var shrink_limit, stretch_limit, font_step: integer;
f: internal_font_number;
auto_expand: boolean;
begin
@@ -17200,23 +17182,23 @@ begin
if f = null_font then
pdf_error("font expansion", "invalid font identifier");
if pdf_font_blink[f] <> null_font then
- pdf_error("font expansion", "\pdffontexpand cannot be used this way (the base font has been expanded or letter-spaced)");
+ pdf_error("font expansion", "\pdffontexpand cannot be used this way (the base font has been expanded)");
scan_optional_equals;
scan_int;
- font_stretch := fix_int(cur_val, 0, 1000);
+ stretch_limit := fix_int(cur_val, 0, 1000);
scan_int;
- font_shrink := fix_int(cur_val, 0, 500);
+ shrink_limit := fix_int(cur_val, 0, 500);
scan_int;
font_step := fix_int(cur_val, 0, 100);
if font_step = 0 then
pdf_error("font expansion", "invalid step");
- font_stretch := font_stretch - font_stretch mod font_step;
- if font_stretch < 0 then
- font_stretch := 0;
- font_shrink := font_shrink - font_shrink mod font_step;
- if font_shrink < 0 then
- font_shrink := 0;
- if (font_stretch = 0) and (font_shrink = 0) then
+ stretch_limit := stretch_limit - stretch_limit mod font_step;
+ if stretch_limit < 0 then
+ stretch_limit := 0;
+ shrink_limit := shrink_limit - shrink_limit mod font_step;
+ if shrink_limit < 0 then
+ shrink_limit := 0;
+ if (stretch_limit = 0) and (shrink_limit = 0) then
pdf_error("font expansion", "invalid limit(s)");
auto_expand := false;
if scan_keyword("autoexpand") then begin
@@ -17230,37 +17212,60 @@ begin
if (pdf_font_step[f] <> 0) then
{this font has been expanded, ensure the expansion parameters are identical}
begin
- if (pdf_font_step[f] <> font_step) or
- ((pdf_font_stretch[f] = null_font) and (font_stretch <> 0)) or
- ((pdf_font_stretch[f] <> null_font) and
- (pdf_font_expand_ratio[pdf_font_stretch[f]] <> font_stretch)) or
- ((pdf_font_shrink[f] = null_font) and (font_shrink <> 0)) or
+ if pdf_font_step[f] <> font_step then
+ pdf_error("font expansion", "font has been expanded with different expansion step");
+
+ if ((pdf_font_stretch[f] = null_font) and (stretch_limit <> 0)) or
+ ((pdf_font_stretch[f] <> null_font) and
+ (pdf_font_expand_ratio[pdf_font_stretch[f]] <> stretch_limit)) then
+ pdf_error("font expansion", "font has been expanded with different stretch limit");
+
+ if ((pdf_font_shrink[f] = null_font) and (shrink_limit <> 0)) or
((pdf_font_shrink[f] <> null_font) and
- (pdf_font_expand_ratio[pdf_font_shrink[f]] <> -font_shrink)) or
- (pdf_font_auto_expand[f] <> auto_expand)
- then
- pdf_error("font expansion", "font has been expanded with different parameters");
+ (-pdf_font_expand_ratio[pdf_font_shrink[f]] <> shrink_limit)) then
+ pdf_error("font expansion", "font has been expanded with different shrink limit");
+
+ if pdf_font_auto_expand[f] <> auto_expand then
+ pdf_error("font expansion", "font has been expanded with different auto expansion value");
end
else begin
- if pdf_font_type[f] <> new_font_type then
+ if (pdf_font_type[f] <> new_font_type) and (pdf_font_type[f] <> virtual_font_type) then
pdf_warning("font expansion", "font should be expanded before its first use",
true, true);
- set_expand_params(f, auto_expand, font_stretch, font_shrink, font_step, 0);
+ set_expand_params(f, auto_expand, stretch_limit, shrink_limit, font_step, 0);
if pdf_font_type[f] = virtual_font_type then
vf_expand_local_fonts(f);
end;
end;
+@ We implement robust letter spacing using virtual font.
+
+@d 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
+
+@p
function letter_space_font(u: pointer; f: internal_font_number; e: integer): internal_font_number;
var k: internal_font_number;
- w, r, fs: scaled;
+ w, r: scaled;
s: str_number;
i, nw: integer;
old_setting:0..max_selector;
+ vf_z: integer;
+ vf_alpha: integer;
+ vf_beta: 1..16;
begin
{read a new font and expand the character widths}
k := read_font_info(u, font_name[f], "", font_size[f]);
- set_no_ligatures(k); {disable ligatures for letter-spaced fonts}
+ if scan_keyword("nolig") then
+ set_no_ligatures(k); {disable ligatures for letter-spaced fonts}
nw := height_base[k] - width_base[k];
for i := 0 to nw - 1 do
font_info[width_base[k] + i].sc :=
@@ -17288,8 +17293,7 @@ begin
vf_default_font[k] := vf_nf - 1;
pdf_font_type[k] := virtual_font_type;
- fs := font_size[f];
- vf_z := fs;
+ vf_z := font_size[f];
vf_replace_z;
w := round_xn_over_d(quad(f), e, 2000);
if w > 0 then
@@ -17363,6 +17367,106 @@ begin
equiv(u):=f; eqtb[font_id_base+f]:=eqtb[u]; font_id_text(f):=t;
end;
+function is_letterspaced_font(f: internal_font_number): boolean;
+label done;
+var i, j: pool_pointer;
+begin
+ is_letterspaced_font := false;
+ if pdf_font_type[f] <> virtual_font_type then
+ return;
+ i := str_start[font_name[f] + 1] - 1;
+ j := str_start[font_name[f]];
+ if (str_pool[i - 1] <> 'l') or (str_pool[i] <> 's') then
+ return;
+ i := i - 2;
+ while i >= j do begin
+ if (str_pool[i] < '0') or (str_pool[i] > '9') then
+ goto done;
+ i := i - 1;
+ end;
+done:
+ if i < j then
+ return;
+ if (str_pool[i] <> '+') and (str_pool[i] <> '-') then
+ return;
+ is_letterspaced_font := true;
+end;
+
+function copy_font_info(f: internal_font_number): internal_font_number;
+{create a copy of |f| in the font mem}
+var lf, bc, ec, i: halfword;
+ k: internal_font_number;
+begin
+ if (pdf_font_expand_ratio[f] <> 0) or (pdf_font_step[f] <> 0) then
+ pdf_error("\pdfcopyfont", "cannot copy an expanded font");
+ if is_letterspaced_font(f) then
+ pdf_error("\pdfcopyfont", "cannot copy a letterspaced font");
+
+ k := font_ptr + 1;
+ incr(font_ptr);
+ if (font_ptr >= font_max) then
+ overflow("maximum internal font number (font_max)", font_max);
+ font_name[k] := font_name[f];
+ font_area[k] := non_existent_path; {to avoid interferences with |new_font()| and |tfm_lookup()|}
+ hyphen_char[k] := hyphen_char[f];
+ skew_char[k] := skew_char[f];
+ font_bchar[k] := font_bchar[f];
+ font_false_bchar[k] := font_false_bchar[f];
+ font_bc[k] := font_bc[f];
+ font_ec[k] := font_ec[f];
+ font_size[k] := font_size[f];
+ font_dsize[k] := font_dsize[f];
+ font_params[k] := font_params[f];
+ font_glue[k] := font_glue[f];
+ bchar_label[k] := bchar_label[f];
+
+ {set base addresses}
+ bc := font_bc[f];
+ ec := font_ec[f];
+ char_base[k] := fmem_ptr - bc;
+ width_base[k] := char_base[k] + ec + 1;
+
+ height_base[k] := width_base[k] + (height_base[f] - width_base[f]);
+ depth_base[k] := height_base[k] + (depth_base[f] - height_base[f]);
+ italic_base[k] := depth_base[k] + (italic_base[f] - depth_base[f]);
+ lig_kern_base[k] := italic_base[k] + (lig_kern_base[f] - italic_base[f]);
+ kern_base[k] := lig_kern_base[k] + (kern_base[f] - lig_kern_base[f]);
+ exten_base[k] := kern_base[k] + (exten_base[f] - kern_base[f]);
+ param_base[k] := exten_base[k] + (param_base[f] - exten_base[f]);
+
+ {allocate memory for the new font |k| and copy data from |f|}
+ lf := (param_base[f] - char_base[f]) + font_params[f] + 1;
+ if (fmem_ptr + lf >= font_mem_size) then
+ overflow("number of words of font memory (font_mem_size)", font_mem_size);
+ for i := 0 to lf - 1 do
+ font_info[char_base[k] + bc + i] := font_info[char_base[f] + bc + i];
+ fmem_ptr := fmem_ptr + lf;
+
+ copy_font_info := k;
+end;
+
+procedure make_font_copy(a: small_number);
+{make a font copy for further use with font expansion}
+var u:pointer; {user's font identifier}
+@!t:str_number; {name for the frozen font identifier}
+@!old_setting:0..max_selector; {holds |selector| setting}
+@!f, k:internal_font_number;
+begin
+ get_r_token; u:=cur_cs;
+ if u>=hash_base then t:=text(u)
+ else if u>=single_base then
+ if u=null_cs then t:="FONT"@+else t:=u-single_base
+ else begin old_setting:=selector; selector:=new_string;
+ print("FONT"); print(u-active_base); selector:=old_setting;
+ @.FONTx@>
+ str_room(1); t:=make_string;
+ end;
+ define(u,set_font,null_font); scan_optional_equals; scan_font_ident;
+ k := cur_val;
+ f := copy_font_info(k);
+ equiv(u):=f; eqtb[font_id_base+f]:=eqtb[u]; font_id_text(f):=t;
+end;
+
@ We need to hold information about used characters in each font for partial
downloading.
@@ -17386,50 +17490,24 @@ created by |tokens_to_string|}
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
+@d bad_vf(#) == vf_error(font_name[f], #) {quit with an error message telling the vf filename}
@<Glob...@>=
@!vf_packet_base: ^integer; {base addresses of character packets from virtual fonts}
@@ -17441,34 +17519,46 @@ processing with an error message}
@!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
+or loaded, otherwise sets |pdf_font_type| to |virtual_font_type|. To
process font definitions in virtual font we call |vf_def_font|.
-@p procedure vf_replace_z;
+@p
+procedure vf_error(filename, msg: str_number);
+var old_setting:0..max_selector; {holds print |selector|}
+ s: str_number;
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;
+ str_room(length(filename) + 3);
+ old_setting:=selector; selector:=new_string;
+ print(filename);
+ print(".vf");
+ s := make_string;
+ selector:=old_setting;
+ pdf_error(s, msg);
+end;
+
+function vf_byte: eight_bits; {read a byte from |vf_file|}
+var i: integer;
+begin
+ i := getc(vf_file);
+ if i < 0 then
+ pdf_error("vf", "unexpected EOF or error");
+ vf_byte := i;
end;
function vf_read(k: integer): integer; {read |k| bytes as an integer from \.{VF} file}
var i: integer;
begin
- i := 0;
+ pdfassert((k > 0) and (k <= 4));
+ i := vf_byte;
+ if (k = 4) and (i > 127) then
+ i := i - 256;
+ decr(k);
while k > 0 do begin
i := i*256 + vf_byte;
decr(k);
@@ -17496,15 +17586,13 @@ var k: internal_font_number;
cs: four_quarters;
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);
+ fs := sqxfw(vf_read(4), font_size[f]);
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}
+ call_func(vf_byte); {skip the font path}
end;
str_room(tmp_b1);
while tmp_b1 > 0 do begin
@@ -17528,23 +17616,19 @@ begin
if (pdf_font_step[f] <> 0) then
set_expand_params(k, pdf_font_auto_expand[f],
pdf_font_expand_ratio[pdf_font_stretch[f]],
- pdf_font_expand_ratio[pdf_font_shrink[f]],
+ -pdf_font_expand_ratio[pdf_font_shrink[f]],
pdf_font_step[f], pdf_font_expand_ratio[f]);
vf_def_font := k;
end;
-procedure do_vf; {process \.{VF} file with font internal number |f|}
-label vf_error;
+procedure do_vf(f: internal_font_number); {process \.{VF} file with font internal number |f|}
var cmd, k, n: integer;
- cc, cmd_length: integer;
+ cc, cmd_length, packet_length: integer;
tfm_width: scaled;
- vf_err_str, s: str_number;
+ s: str_number;
stack_level: vf_stack_index;
save_vf_nf: internal_font_number;
- f: internal_font_number;
-
begin
- f := tmp_f;
pdf_font_type[f] := real_font_type;
if auto_expand_vf(f) then
return; {auto-expanded virtual font}
@@ -17560,16 +17644,6 @@ begin
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@>=
@@ -17584,7 +17658,7 @@ 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;
+ call_func(vf_byte); {skip the comment}
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
@@ -17600,9 +17674,7 @@ if vf_read(4) div @'20 <> font_dsize[f] then begin
print(font_name[f]);
print(".vf ignored");
end;
-update_terminal;
-vf_z := font_size[f];
-vf_replace_z
+update_terminal
@ @<Process the font definitions@>=
cmd := vf_byte;
@@ -17622,38 +17694,36 @@ vf_local_font_num[f] := vf_nf - save_vf_nf;
@ @<Build a character packet@>=
if cmd = long_char then begin
- vf_packet_length := vf_read(4);
+ 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);
+ tfm_width := sqxfw(vf_read(4), font_size[f]);
end
else begin
- vf_packet_length := cmd;
+ 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);
+ tfm_width := sqxfw(vf_read(3), font_size[f]);
end;
-if vf_packet_length < 0 then
+if packet_length < 0 then
bad_vf("negative packet length");
-if vf_packet_length > vf_max_packet_length then
+if 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
+if abs(tfm_width - char_width(f)(char_info(f)(cc))) > 1 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
+str_room(packet_length);
+while packet_length > 0 do begin
cmd := vf_byte;
- decr(vf_packet_length);
+ decr(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;
+ packet_length := packet_length - cmd_length;
while cmd_length > 0 do begin
decr(cmd_length);
append_char(vf_byte);
@@ -17661,7 +17731,7 @@ while vf_packet_length > 0 do begin
end;
if stack_level <> 0 then
bad_vf("more PUSHs than POPs in character packet");
-if vf_packet_length <> 0 then
+if packet_length <> 0 then
bad_vf("invalid packet length or DVI command in packet");
@<Store the packet being built@>;
cmd := vf_byte
@@ -17678,7 +17748,7 @@ 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);
+ packet_length := packet_length - (cmd - fnt1 + 1);
end
else
k := cmd - fnt_num_0;
@@ -17711,7 +17781,7 @@ 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);
+ packet_length := packet_length - (cmd - xxx1 + 1);
if cmd_length > vf_max_packet_length then
bad_vf("packet length too long");
if cmd_length < 0 then
@@ -17739,6 +17809,49 @@ othercases
bad_vf("improver DVI command");
endcases
+@ @p
+procedure pdf_check_vf_cur_val;
+var f: internal_font_number;
+begin
+ f := cur_val;
+ do_vf(f);
+ if pdf_font_type[f] = virtual_font_type then
+ pdf_error("font", "command cannot be used with virtual font");
+end;
+
+function auto_expand_vf(f: internal_font_number): boolean;
+{check for a virtual auto-expanded font}
+var bf, lf: internal_font_number;
+ e, k: integer;
+begin
+ auto_expand_vf := false;
+ if (not pdf_font_auto_expand[f]) or (pdf_font_blink[f] = null_font) then
+ return; {not an auto-expanded font}
+ bf := pdf_font_blink[f];
+ if pdf_font_type[bf] = new_font_type then {we must process the base font first}
+ do_vf(bf);
+ if pdf_font_type[bf] <> virtual_font_type then
+ return; {not a virtual font}
+
+ e := pdf_font_expand_ratio[f];
+ for k := 0 to vf_local_font_num[bf] - 1 do begin
+ lf := vf_default_font[bf] + k;
+ allocvffnts;
+ {copy vf local font numbers:}
+ vf_e_fnts[vf_nf] := vf_e_fnts[lf];
+ {definition of local vf fonts are expanded from base fonts:}
+ vf_i_fnts[vf_nf] := auto_expand_font(vf_i_fnts[lf], e);
+ copy_expand_params(vf_i_fnts[vf_nf], vf_i_fnts[lf], e);
+ incr(vf_nf);
+ end;
+ vf_packet_base[f] := vf_packet_base[bf];
+ vf_local_font_num[f] := vf_local_font_num[bf];
+ vf_default_font[f] := vf_nf - vf_local_font_num[f];
+
+ pdf_font_type[f] := virtual_font_type;
+ auto_expand_vf := true;
+end;
+
@ 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
@@ -17771,7 +17884,11 @@ vf_stack_ptr := 0;
character packet}
var i: integer;
begin
- i := 0;
+ pdfassert((k > 0) and (k <= 4));
+ i := packet_byte;
+ if (k = 4) and (i > 127) then
+ i := i - 256;
+ decr(k);
while k > 0 do begin
i := i*256 + packet_byte;
decr(k);
@@ -17779,43 +17896,27 @@ begin
packet_read := i;
end;
-function packet_scaled(k: integer): integer; {get |k| bytes from packet as a
+function packet_scaled(k: integer; fs: scaled): scaled; {get |k| bytes from packet as a
scaled}
-var s: scaled;
+var fw: integer;
begin
+ fw := packet_read(k);
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");
+ 1: if fw > 127 then
+ fw := fw - 256;
+ 2: if fw > @"8000 then
+ fw := fw - @"10000;
+ 3: if fw > @"800000 then
+ fw := fw - @"1000000;
endcases;
- packet_scaled := s;
+ packet_scaled := sqxfw(fw, fs);
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|}
+procedure do_vf_packet(vf_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_vf, k, n: internal_font_number;
- save_h, save_v: scaled;
+var f, k, n: internal_font_number;
+ save_cur_h, save_cur_v: scaled;
cmd: integer;
char_move: boolean;
w, x, y, z: scaled;
@@ -17824,32 +17925,28 @@ 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;
+ save_cur_v := cur_v;
+ save_cur_h := cur_h;
+ push_packet_state; {save pointer and length of the current packet}
+ start_packet(vf_f, c); {set pointer and length of the new packet}
+ f := vf_i_fnts[vf_default_font[vf_f]];
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;
+ pop_packet_state; {restore pointer and length of the previous packet}
+ cur_v := save_cur_v;
+ cur_h := save_cur_h;
decr(vf_cur_s);
end;
@ The following code typesets a character to PDF output.
-@d output_one_char(#)==begin
- pdf_check_new_font(f);
+@d output_one_char(#) == begin
+ if pdf_font_type[f] = new_font_type then
+ do_vf(f);
if pdf_font_type[f] = virtual_font_type then
do_vf_packet(f, #)
else begin
@@ -17859,7 +17956,6 @@ end;
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
@@ -17876,13 +17972,13 @@ else if ((fnt_num_0 <= cmd) and (cmd <= fnt_num_0 + 63)) or (cmd = fnt1) then be
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
+ while (n < vf_local_font_num[vf_f]) and
+ (vf_e_fnts[vf_default_font[vf_f] + n] <> k) do
incr(n);
- if (n = vf_local_font_num[save_vf]) then
+ if (n = vf_local_font_num[vf_f]) then
pdf_error("vf", "local font not found")
else
- f := vf_i_fnts[vf_default_font[save_vf] + n];
+ f := vf_i_fnts[vf_default_font[vf_f] + n];
end
else case cmd of
push: begin
@@ -17920,8 +18016,8 @@ four_cases(set1), four_cases(put1): begin
goto do_char;
end;
set_rule, put_rule: begin
- rule_ht := packet_scaled(4);
- rule_wd := packet_scaled(4);
+ rule_ht := packet_scaled(4, font_size[vf_f]);
+ rule_wd := packet_scaled(4, font_size[vf_f]);
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
@@ -17929,27 +18025,27 @@ set_rule, put_rule: begin
end;
end;
four_cases(right1):
- cur_h := cur_h + packet_scaled(cmd - right1 + 1);
+ cur_h := cur_h + packet_scaled(cmd - right1 + 1, font_size[vf_f]);
w0, four_cases(w1): begin
if cmd > w0 then
- w := packet_scaled(cmd - w0);
+ w := packet_scaled(cmd - w0, font_size[vf_f]);
cur_h := cur_h + w;
end;
x0, four_cases(x1): begin
if cmd > x0 then
- x := packet_scaled(cmd - x0);
+ x := packet_scaled(cmd - x0, font_size[vf_f]);
cur_h := cur_h + x;
end;
four_cases(down1):
- cur_v := cur_v + packet_scaled(cmd - down1 + 1);
+ cur_v := cur_v + packet_scaled(cmd - down1 + 1, font_size[vf_f]);
y0, four_cases(y1): begin
if cmd > y0 then
- y := packet_scaled(cmd - y0);
+ y := packet_scaled(cmd - y0, font_size[vf_f]);
cur_v := cur_v + y;
end;
z0, four_cases(z1): begin
if cmd > z0 then
- z := packet_scaled(cmd - z0);
+ z := packet_scaled(cmd - z0, font_size[vf_f]);
cur_v := cur_v + z;
end;
four_cases(xxx1): begin
@@ -18536,7 +18632,7 @@ 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}
+ obj_aux(pdf_last_page) := 1; {mark that this page has been created}
pdf_new_dict(obj_type_others, 0, 0);
pdf_last_stream := obj_ptr;
cur_h := cur_h_offset;
@@ -18928,14 +19024,13 @@ if pdf_link_list <> null then begin
i := obj_annot_ptr(info(k));
pdf_begin_dict(info(k), 1);
pdf_print_ln("/Type /Annot");
+ if pdf_action_type(pdf_link_action(i)) <> pdf_action_user then
+ pdf_print_ln("/Subtype /Link");
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");
+ if pdf_action_type(pdf_link_action(i)) <> pdf_action_user then
pdf_print("/A ");
- end;
write_action(pdf_link_action(i));
pdf_end_dict;
k := link(k);
@@ -19350,7 +19445,9 @@ for k := font_base + 1 to font_ptr do
print_font_identifier(i);
print(" and ");
print_font_identifier(k);
- print(" has conflicting attributes"); print_ln; print_ln;
+ print(" have conflicting attributes; I will ignore the attributes assigned to ");
+ print_font_identifier(i);
+ print_ln; print_ln;
end;
end;
fixed_gen_tounicode := pdf_gen_tounicode;
@@ -19645,7 +19742,7 @@ print_mod_date;
@ @<Output the |obj_tab|@>=
l := 0;
for k := 1 to sys_obj_ptr do
- if obj_offset(k) = 0 then begin
+ if not is_obj_written(k) then begin
obj_link(l) := k;
l := k;
end;
@@ -19656,7 +19753,7 @@ 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
+ if not is_obj_written(k) then begin
pdf_print_fw_int(obj_link(k), 10);
pdf_print_ln(" 00000 f ");
end
@@ -19678,7 +19775,7 @@ else
xref_offset_width := 1;
l := 0;
for k := 1 to sys_obj_ptr do
- if obj_offset(k) = 0 then begin
+ if not is_obj_written(k) then begin
obj_link(l) := k;
l := k;
end;
@@ -19701,7 +19798,7 @@ print_ID(output_file_name);
pdf_print_nl;
pdf_begin_stream;
for k := 0 to sys_obj_ptr do begin
- if obj_offset(k) = 0 then begin {a free object}
+ if not is_obj_written(k) then begin {a free object}
pdf_out(0);
pdf_out_bytes(obj_link(k), xref_offset_width);
pdf_out(255);
@@ -19842,8 +19939,8 @@ location |adjust_tail|.
@ @<Glob...@>=
@!pdf_font_blink: ^internal_font_number; {link to base font (used for expanded fonts only)}
@!pdf_font_elink: ^internal_font_number; {link to expanded fonts (used for base fonts only)}
-@!pdf_font_stretch: ^integer; {limit of stretching}
-@!pdf_font_shrink: ^integer; {limit of shrinking}
+@!pdf_font_stretch: ^integer; {link to font expanded by stretch limi}
+@!pdf_font_shrink: ^integer; {link to font expanded by shrink limit}
@!pdf_font_step: ^integer; {amount of one step of expansion}
@!pdf_font_expand_ratio: ^integer; {expansion ratio of a particular font}
@!pdf_font_auto_expand: ^boolean; {this font is auto-expanded?}
@@ -19921,8 +20018,8 @@ begin
k := pdf_font_shrink[f];
if k <> null_font then begin
if max_shrink_ratio < 0 then
- max_shrink_ratio := pdf_font_expand_ratio[k]
- else if max_shrink_ratio <> pdf_font_expand_ratio[k] then
+ max_shrink_ratio := -pdf_font_expand_ratio[k]
+ else if max_shrink_ratio <> -pdf_font_expand_ratio[k] then
pdf_error("font expansion", "using fonts with different limit of expansion in one paragraph is not allowed");
end;
check_expand_pars := true;
@@ -20002,12 +20099,17 @@ begin
return;
l := prev_char_p;
r := link(p);
- if type(l) = ligature_node then
- l := lig_char(l);
- if type(r) = ligature_node then
- r := lig_char(r);
- if not (is_char_node(l) and is_char_node(r) and
- (font(l) = font(r)) and
+ if not is_char_node(l) then
+ if type(l) = ligature_node then
+ l := lig_char(l)
+ else
+ return;
+ if not is_char_node(r) then
+ if type(r) = ligature_node then
+ r := lig_char(r)
+ else
+ return;
+ if not ((font(l) = font(r)) and
(pdf_font_stretch[font(l)] <> null_font))
then
return;
@@ -20026,12 +20128,17 @@ begin
return;
l := prev_char_p;
r := link(p);
- if type(l) = ligature_node then
- l := lig_char(l);
- if type(r) = ligature_node then
- r := lig_char(r);
- if not (is_char_node(l) and is_char_node(r) and
- (font(l) = font(r)) and
+ if not is_char_node(l) then
+ if type(l) = ligature_node then
+ l := lig_char(l)
+ else
+ return;
+ if not is_char_node(r) then
+ if type(r) = ligature_node then
+ r := lig_char(r)
+ else
+ return;
+ if not ((font(l) = font(r)) and
(pdf_font_shrink[font(l)] <> null_font))
then
return;
@@ -20073,13 +20180,13 @@ begin
if ef = 0 then
return;
if (pdf_font_stretch[f] <> null_font) and (ex_ratio > 0) then
- k := expand_font(f, divide_scaled(ex_ratio*
- pdf_font_expand_ratio[pdf_font_stretch[f]]*ef,
- 1000000, 0))
+ k := expand_font(f, ext_xn_over_d(ex_ratio*ef,
+ pdf_font_expand_ratio[pdf_font_stretch[f]],
+ 1000000))
else if (pdf_font_shrink[f] <> null_font) and (ex_ratio < 0) then
- k := expand_font(f, -divide_scaled(ex_ratio*
- pdf_font_expand_ratio[pdf_font_shrink[f]]*ef,
- 1000000, 0))
+ k := expand_font(f, ext_xn_over_d(ex_ratio*ef,
+ -pdf_font_expand_ratio[pdf_font_shrink[f]],
+ 1000000))
else
k := f;
if k <> f then begin
@@ -20228,30 +20335,32 @@ if p<>null then
x := x + width(p);
end;
kern_node: begin
- if (m = cal_expand_ratio) and (subtype(p) = normal) then begin
- k := kern_stretch(p);
- if k <> 0 then begin
- subtype(p) := substituted;
- font_stretch := font_stretch + k;
- end;
- k := kern_shrink(p);
- if k <> 0 then begin
- subtype(p) := substituted;
- font_shrink := font_shrink + k;
+ if subtype(p) = normal then begin
+ if m = cal_expand_ratio then begin
+ font_stretch := font_stretch + kern_stretch(p);
+ font_shrink := font_shrink + kern_shrink(p);
+ end
+ else if m = subst_ex_font then begin
+ if font_expand_ratio > 0 then
+ k := kern_stretch(p)
+ else if font_expand_ratio < 0 then
+ k := kern_shrink(p)
+ else
+ pdfassert(0);
+ if k <> 0 then begin
+ if is_char_node(link(p)) then
+ width(p) := get_kern(font(prev_char_p),
+ character(prev_char_p),
+ character(link(p)))
+ else if type(link(p)) = ligature_node then
+ width(p) := get_kern(font(prev_char_p),
+ character(prev_char_p),
+ character(lig_char(link(p))));
+ end;
end;
- end
- else if (m = subst_ex_font) and (subtype(p) = substituted) then begin
- if type(link(p)) = ligature_node then
- width(p) := get_kern(font(prev_char_p),
- character(prev_char_p),
- character(lig_char(link(p))))
- else
- width(p) := get_kern(font(prev_char_p),
- character(prev_char_p),
- character(link(p)))
- end;
- x := x + width(p);
end;
+ x := x + width(p);
+ end;
math_node: begin x:=x+width(p);
if TeXXeT_en then @<Adjust \(t)the LR stack for the |hpack| routine@>;
end;
@@ -20659,7 +20768,7 @@ baselineskip calculation is handled by the |append_to_vlist| routine.
@p procedure append_to_vlist(@!b:pointer);
var d:scaled; {deficiency of space between baselines}
@!p:pointer; {a new glue specification}
-begin if prev_depth>ignore_depth then
+begin if prev_depth>pdf_ignored_dimen then
begin d:=width(baseline_skip)-prev_depth-height(b);
if d<line_skip_limit then p:=new_param_glue(line_skip_code)
else begin p:=new_skip_param(baseline_skip_code);
@@ -22905,7 +23014,7 @@ entered, so that the columns will generate a list for subsequent packaging.
procedure init_span(@!p:pointer);
begin push_nest;
if mode=-hmode then space_factor:=1000
-else begin prev_depth:=ignore_depth; normal_paragraph;
+else begin prev_depth:=pdf_ignored_dimen; normal_paragraph;
end;
cur_span:=p;
end;
@@ -25221,14 +25330,21 @@ if left_skip<>zero_glue then
link(r):=q; q:=r;
end
+@ @<Initialize table entries...@>=
+pdf_ignored_dimen := ignore_depth;
+pdf_each_line_height := pdf_ignored_dimen;
+pdf_each_line_depth := pdf_ignored_dimen;
+pdf_first_line_height := pdf_ignored_dimen;
+pdf_last_line_depth := pdf_ignored_dimen;
+
@ @<Append the new box to the current vertical list...@>=
-if pdf_each_line_height <> 0 then
+if pdf_each_line_height <> pdf_ignored_dimen then
height(just_box) := pdf_each_line_height;
-if pdf_each_line_depth <> 0 then
+if pdf_each_line_depth <> pdf_ignored_dimen then
depth(just_box) := pdf_each_line_depth;
-if (pdf_first_line_height <> 0) and (cur_line = prev_graf + 1) then
+if (pdf_first_line_height <> pdf_ignored_dimen) 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
+if (pdf_last_line_depth <> pdf_ignored_dimen) and (cur_line + 1 = best_line) then
depth(just_box) := pdf_last_line_depth;
if pre_adjust_head <> pre_adjust_tail then
append_list(pre_adjust_head)(pre_adjust_tail);
@@ -27838,7 +27954,7 @@ end
@ @<Fire up the user's output routine and |return|@>=
begin output_active:=true;
incr(dead_cycles);
-push_nest; mode:=-vmode; prev_depth:=ignore_depth; mode_line:=-line;
+push_nest; mode:=-vmode; prev_depth:=pdf_ignored_dimen; mode_line:=-line;
begin_token_list(output_routine,output_text);
new_save_level(output_group); normal_paragraph;
scan_left_brace;
@@ -28474,11 +28590,11 @@ is short, since the |scan_rule_spec| routine already does most of what is
required; thus, there is no need for a special action procedure.
Note that baselineskip calculations are disabled after a rule in vertical
-mode, by setting |prev_depth:=ignore_depth|.
+mode, by setting |prev_depth:=pdf_ignored_dimen|.
@<Cases of |main_control| that build...@>=
vmode+hrule,hmode+vrule,mmode+vrule: begin tail_append(scan_rule_spec);
- if abs(mode)=vmode then prev_depth:=ignore_depth
+ if abs(mode)=vmode then prev_depth:=pdf_ignored_dimen
else if abs(mode)=hmode then space_factor:=1000;
end;
@@ -29003,7 +29119,7 @@ else begin if k=vmode then scan_spec(vbox_group,true)
end;
push_nest; mode:=-k;
if k=vmode then
- begin prev_depth:=ignore_depth;
+ begin prev_depth:=pdf_ignored_dimen;
if every_vbox<>null then begin_token_list(every_vbox,every_vbox_text);
end
else begin space_factor:=1000;
@@ -29204,7 +29320,7 @@ else
saved(1) := 0;
save_ptr := save_ptr + 2;
new_save_level(insert_group); scan_left_brace; normal_paragraph;
-push_nest; mode:=-vmode; prev_depth:=ignore_depth;
+push_nest; mode:=-vmode; prev_depth:=pdf_ignored_dimen;
end;
@ @<Cases of |handle...@>=
@@ -30138,7 +30254,7 @@ end
@ @<Cases of |main_control| that build...@>=
mmode+vcenter: begin scan_spec(vcenter_group,false); normal_paragraph;
- push_nest; mode:=-vmode; prev_depth:=ignore_depth;
+ push_nest; mode:=-vmode; prev_depth:=pdf_ignored_dimen;
if every_vbox<>null then begin_token_list(every_vbox,every_vbox_text);
end;
@@ -30764,6 +30880,7 @@ any_mode(def_family),
any_mode(set_font),
any_mode(def_font),
any_mode(letterspace_font),
+any_mode(pdf_copy_font),
any_mode(register),
any_mode(advance),
any_mode(multiply),
@@ -31506,6 +31623,7 @@ endcases;
@<Assignments@>=
def_font: new_font(a);
letterspace_font: new_letterspaced_font(a);
+pdf_copy_font: make_font_copy(a);
@ @<Declare subprocedures for |prefixed_command|@>=
procedure new_font(@!a:small_number);
@@ -31947,6 +32065,7 @@ begin @<If dumping is not allowed, abort@>;
@<Dump the table of equivalents@>;
@<Dump the font information@>;
@<Dump the hyphenation tables@>;
+@<Dump pdftex data@>;
@<Dump a couple more things and the closing check word@>;
@<Close the format file@>;
end;
@@ -31976,7 +32095,9 @@ begin @<Undump constants for consistency check@>;
@<Undump the table of equivalents@>;
@<Undump the font information@>;
@<Undump the hyphenation tables@>;
+@<Undump pdftex data@>;
@<Undump a couple more things and the closing check word@>;
+prev_depth := pdf_ignored_dimen;
load_fmt_file:=true; return; {it worked!}
bad_fmt: wake_up_terminal;
wterm_ln('(Fatal format file error; I''m stymied)');
@@ -32367,6 +32488,78 @@ while j>0 do
end;
@!init trie_not_ready:=false @+tini
+@ Store some of the pdftex data structures in the format. The idea here is
+to ensure that any data structures referenced from pdftex-specific whatsit
+nodes are retained. For the sake of simplicity and speed, all the filled parts
+of |pdf_mem| and |obj_tab| are retained, in the present implementation. We also
+retain three of the linked lists that start from |head_tab|, so that it is
+possible to, say, load an image in the \.{INITEX} run and then reference it in a
+\.{VIRTEX} run that uses the dumped format.
+
+@<Dump pdftex data@>=
+begin
+dumpimagemeta; {the image information array }
+dump_int(pdf_mem_size);
+dump_int(pdf_mem_ptr);
+for k:=1 to pdf_mem_ptr-1 do begin
+ dump_int(pdf_mem[k]);
+ end;
+print_ln; print_int(pdf_mem_ptr-1); print(" words of pdfTeX memory");
+dump_int(obj_tab_size);
+dump_int(obj_ptr);
+dump_int(sys_obj_ptr);
+for k:=1 to sys_obj_ptr do begin
+ dump_int(obj_tab[k].int0);
+ dump_int(obj_tab[k].int1);
+ dump_int(obj_tab[k].int3);
+ dump_int(obj_tab[k].int4);
+ end;
+print_ln; print_int(sys_obj_ptr); print(" indirect objects");
+dump_int(pdf_obj_count);
+dump_int(pdf_xform_count);
+dump_int(pdf_ximage_count);
+dump_int(head_tab[obj_type_obj]);
+dump_int(head_tab[obj_type_xform]);
+dump_int(head_tab[obj_type_ximage]);
+dump_int(pdf_last_obj);
+dump_int(pdf_last_xform);
+dump_int(pdf_last_ximage);
+end
+
+@ And restoring the pdftex data structures from the format. The
+two function arguments to |undumpimagemeta| have been restored
+already in an earlier module.
+
+@<Undump pdftex data@>=
+begin
+undumpimagemeta(pdf_minor_version,pdf_inclusion_errorlevel); {the image information array }
+undump_int(pdf_mem_size);
+pdf_mem := xrealloc_array(pdf_mem, integer, pdf_mem_size);
+undump_int(pdf_mem_ptr);
+for k:=1 to pdf_mem_ptr-1 do begin
+ undump_int(pdf_mem[k]);
+ end;
+undump_int(obj_tab_size);
+undump_int(obj_ptr);
+undump_int(sys_obj_ptr);
+for k:=1 to sys_obj_ptr do begin
+ undump_int(obj_tab[k].int0);
+ undump_int(obj_tab[k].int1);
+ obj_tab[k].int2 := -1;
+ undump_int(obj_tab[k].int3);
+ undump_int(obj_tab[k].int4);
+ end;
+undump_int(pdf_obj_count);
+undump_int(pdf_xform_count);
+undump_int(pdf_ximage_count);
+undump_int(head_tab[obj_type_obj]);
+undump_int(head_tab[obj_type_xform]);
+undump_int(head_tab[obj_type_ximage]);
+undump_int(pdf_last_obj);
+undump_int(pdf_last_xform);
+undump_int(pdf_last_ximage);
+end
+
@ We have already printed a lot of statistics, so we set |tracing_stats:=0|
to prevent them from appearing again.
@@ -34276,7 +34469,7 @@ begin
f := cur_val;
if f = null_font then
pdf_error("font", "invalid font identifier");
- pdf_check_vf(f);
+ pdf_check_vf_cur_val;
if not font_used[f] then
pdf_init_font(f);
scan_pdf_ext_toks;
@@ -35283,13 +35476,16 @@ begin
pdf_error("ext4", "annotations cannot be inside an XForm");
if doing_leaders then
return;
+ if is_obj_scheduled(pdf_annot_objnum(p)) then
+ pdf_annot_objnum(p) := pdf_new_objnum;
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);
+ set_obj_scheduled(pdf_annot_objnum(p));
end;
-@ To implement nesting link annotations, we need a stack to hold copy of
+@ To implement nested link annotations, we need a stack to hold copy of
|pdf_start_link_node|'s that are being written out, together with their box
nesting level.
@@ -35338,6 +35534,8 @@ begin
if not is_shipping_page then
pdf_error("ext4", "link annotations cannot be inside an XForm");
pdfassert(type(parent_box) = hlist_node);
+ if is_obj_scheduled(pdf_link_objnum(p)) then
+ pdf_link_objnum(p) := pdf_new_objnum;
push_link_level(p);
set_rect_dimens(p, parent_box, x, y,
pdf_width(p), pdf_height(p), pdf_depth(p),
@@ -35345,6 +35543,7 @@ begin
obj_annot_ptr(pdf_link_objnum(p)) := p; {the reference for the pdf annot object
must be set here}
pdf_append_list(pdf_link_objnum(p))(pdf_link_list);
+ set_obj_scheduled(pdf_link_objnum(p));
end;
procedure end_link;