summaryrefslogtreecommitdiff
path: root/Build
diff options
context:
space:
mode:
authorTaco Hoekwater <taco@elvenkind.com>2008-04-11 16:33:03 +0000
committerTaco Hoekwater <taco@elvenkind.com>2008-04-11 16:33:03 +0000
commit047070d4ddd52fec36d80da93125b44e736c4b7c (patch)
tree64708325f5e3c41e72ad1c954b1c1a1210ace4ec /Build
parent0dcc6be38a969303eaa2b695bc7ceb3487e9ad47 (diff)
Metapost 1.003 (binaries)
git-svn-id: svn://tug.org/texlive/trunk@7377 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build')
-rw-r--r--Build/source/texk/web2c/dvitomp.ch16
-rw-r--r--Build/source/texk/web2c/dvitomp.web46
-rw-r--r--Build/source/texk/web2c/lib/texmfmp.c2
-rw-r--r--Build/source/texk/web2c/metapost.mk3
-rw-r--r--Build/source/texk/web2c/mp.ch3
-rw-r--r--Build/source/texk/web2c/mp.web315
-rw-r--r--Build/source/texk/web2c/mpdir/makecpool.c60
-rw-r--r--Build/source/texk/web2c/mpdir/mapfile.c150
-rw-r--r--Build/source/texk/web2c/mpdir/mplib.h218
-rw-r--r--Build/source/texk/web2c/mpdir/utils.c34
-rw-r--r--Build/source/texk/web2c/mpdir/writeenc.c1
-rw-r--r--Build/source/texk/web2c/mpdir/writefont.c19
-rw-r--r--Build/source/texk/web2c/mpdir/writet1.c8
-rw-r--r--Build/source/texk/web2c/mpware/mpto.c13
14 files changed, 342 insertions, 546 deletions
diff --git a/Build/source/texk/web2c/dvitomp.ch b/Build/source/texk/web2c/dvitomp.ch
index efbb18be151..b3393dfc2fe 100644
--- a/Build/source/texk/web2c/dvitomp.ch
+++ b/Build/source/texk/web2c/dvitomp.ch
@@ -26,12 +26,12 @@
@z
@x [1] Duplicate banner line for use in |print_version_and_exit|.
-@d banner=='% Written by DVItoMP, Version 1.002'
+@d banner=='% Written by DVItoMP, Version 1.003'
{the first line of the output file}
@y
-@d banner=='% Written by DVItoMP, Version 1.002/color'
+@d banner=='% Written by DVItoMP, Version 1.003/color'
{the first line of the output file}
-@d term_banner=='This is DVItoMP, Version 1.002/color'
+@d term_banner=='This is DVItoMP, Version 1.003/color'
{the same in the usual format, as it would be shown on a terminal}
@z
@@ -49,12 +49,6 @@ procedure initialize; {this procedure gets things started properly}
@<Set initial values@>@/
@z
-@x [5] Increase parameter(s).
-@!virtual_space=10000;
-@y
-@!virtual_space=100000;
-@z
-
@x [7] Remove non-local goto.
@d abort(#)==begin err_print_ln('DVItoMP abort: ',#);
history:=fatal_error; jump_out;
@@ -817,7 +811,7 @@ l := 1; r := num_named_colors;
found := false;
while (l <= r) and not found do begin
m := (l + r) / 2;
- k := strcmp(buf, named_colors[m].name);
+ k := strcmp(stringcast(buf), named_colors[m].name);
if k = 0 then begin
color_stack[color_stack_depth]:=xstrdup(named_colors[m].value);
found := true;
@@ -828,7 +822,7 @@ while (l <= r) and not found do begin
end;
if not found then begin
color_warn('non-hardcoded color "',stringcast(buf),'" in "color push" command');
- color_stack[color_stack_depth]:=xstrdup(buf);
+ color_stack[color_stack_depth]:=xstrdup(stringcast(buf));
end;
@ Last but not least, this code snippet prints a \.{withcolor} specifier
diff --git a/Build/source/texk/web2c/dvitomp.web b/Build/source/texk/web2c/dvitomp.web
index 85b4dfc732c..da6ce104e44 100644
--- a/Build/source/texk/web2c/dvitomp.web
+++ b/Build/source/texk/web2c/dvitomp.web
@@ -65,7 +65,7 @@ an ``\.{MPX}'' file.
The |banner| string defined here should be changed whenever \.{DVItoMP}
gets modified.
-@d banner=='% Written by DVItoMP, Version 1.002'
+@d banner=='% Written by DVItoMP, Version 1.003'
{the first line of the output file}
@ This program is written in standard \PASCAL, except where it is necessary
@@ -113,15 +113,15 @@ procedure initialize; {this procedure gets things started properly}
reduce \.{DVItoMP}'s capacity.
@<Constants...@>=
-@!max_fonts=100; {maximum number of distinct fonts per \.{DVI} file}
-@!max_fnums=300; {maximum number of fonts plus fonts local to virtual fonts}
-@!max_widths=10000; {maximum number of different characters among all fonts}
-@!virtual_space=10000;
+@!max_fonts=1000; {maximum number of distinct fonts per \.{DVI} file}
+@!max_fnums=3000; {maximum number of fonts plus fonts local to virtual fonts}
+@!max_widths=256*max_fonts; {maximum number of different characters among all fonts}
+@!virtual_space=1000000;
{maximum total bytes of typesetting commands for virtual fonts}
@!line_length=79; {maximum output line length (must be at least 60)}
@!stack_size=100; {\.{DVI} files shouldn't |push| beyond this depth}
-@!name_size=1000; {total length of all font file names}
-@!name_length=50; {a file name shouldn't be longer than this}
+@!name_size=100000; {total length of all font file names}
+@!name_length=250; {a file name shouldn't be longer than this}
@ There is one more parameter that is a little harder to change because
it is of type |real|.
@@ -514,33 +514,38 @@ end;
@#
function get_two_bytes:integer; {returns the next two bytes, unsigned}
var a,@!b:eight_bits;
-begin @<Read two bytes into |a| and |b|@>;
+begin a:=0;b:=0; {for compiler warnings}
+@<Read two bytes into |a| and |b|@>;
get_two_bytes:=a*256+b;
end;
@#
function signed_pair:integer; {returns the next two bytes, signed}
var a,@!b:eight_bits;
-begin @<Read two bytes into |a| and |b|@>;
+begin a:=0;b:=0; {for compiler warnings}
+@<Read two bytes into |a| and |b|@>;
if a<128 then signed_pair:=a*256+b
else signed_pair:=(a-256)*256+b;
end;
@#
function get_three_bytes:integer; {returns the next three bytes, unsigned}
var a,@!b,@!c:eight_bits;
-begin @<Read three bytes into |a|, |b|, and~|c|@>;
+begin a:=0;b:=0;c:=0; {for compiler warnings}
+@<Read three bytes into |a|, |b|, and~|c|@>;
get_three_bytes:=(a*256+b)*256+c;
end;
@#
function signed_trio:integer; {returns the next three bytes, signed}
var a,@!b,@!c:eight_bits;
-begin @<Read three bytes into |a|, |b|, and~|c|@>;
+begin a:=0;b:=0;c:=0; {for compiler warnings}
+@<Read three bytes into |a|, |b|, and~|c|@>;
if a<128 then signed_trio:=(a*256+b)*256+c
else signed_trio:=((a-256)*256+b)*256+c;
end;
@#
function signed_quad:integer; {returns the next four bytes, signed}
var a,@!b,@!c,@!d:eight_bits;
-begin @<Read four bytes into |a|, |b|, |c|, and~|d|@>;
+begin a:=0;b:=0;c:=0;d:=0; {for compiler warnings}
+@<Read four bytes into |a|, |b|, |c|, and~|d|@>;
if a<128 then signed_quad:=((a*256+b)*256+c)*256+d
else signed_quad:=(((a-256)*256+b)*256+c)*256+d;
end;
@@ -802,11 +807,12 @@ while f<nf do
if exact then
begin if abs(font_scaled_size[f]-font_scaled_size[ff])
<= font_tolerance then
- begin if not vf_reading then
+ begin if not vf_reading then begin
if local_only[f] then
begin font_num[f]:=font_num[ff]; local_only[f]:=false;
end
else if font_num[f]<>font_num[ff] then goto 99;
+ end;
goto done;
end;
end
@@ -814,8 +820,9 @@ while f<nf do
end;
99:incr(f);
end;
-done:if f<nf then
+done:if f<nf then begin
@<Make sure fonts |f| and |ff| have matching design sizes and checksums@>;
+ end;
match_font:=f;
end;
@@ -886,9 +893,10 @@ if (nw=0)or(nw>256) then goto 9997;
for k:=1 to 3+lh do
begin if eof(tfm_file) then goto 9997;
read_tfm_word;
- if k=4 then
+ if k=4 then begin
if b0<128 then tfm_check_sum:=((b0*256+b1)*256+b2)*256+b3
else tfm_check_sum:=(((b0-256)*256+b1)*256+b2)*256+b3;
+ end;
end;
@ @<Store character-width indices...@>=
@@ -1040,7 +1048,7 @@ internal font number with the width information loaded.
@p function select_font(@!e:integer):integer;
var @!f:0..max_fonts; {the internal font number}
@!ff:0..max_fonts; {internal font number for an existing version}
-@!k,@!l:integer; {general purpose loop counters}
+@!k:integer; {general purpose loop counter}
begin @<Set |f| to the internal font number that corresponds to |e|,
or |abort| if there is none@>;
if info_base[f]=max_widths then
@@ -1487,7 +1495,8 @@ opcode.
@<Declare a function called |first_par|@>=
function first_par(o:eight_bits):integer;
-begin case o of
+begin first_par:=0; {for compiler warnings}
+case o of
sixty_four_cases(set_char_0),sixty_four_cases(set_char_0+64):
first_par:=o-set_char_0;
set1,put1,fnt1,xxx1,fnt_def1: first_par:=get_byte;
@@ -1531,10 +1540,11 @@ begin o:=get_byte; p:=first_par(o);
if eof(dvi_file) then bad_dvi('the DVI file ended prematurely');
@.the DVI file ended prematurely@>
if o<set1+4 then {|set_char_0| through |set_char_127|, |set1| through |set4|}
- begin if cur_font>max_fnums then
+ begin if cur_font>max_fnums then begin
if vf_reading then
abort('no font selected for character ',p:1,' in virtual font')
else bad_dvi('no font selected for character ',p:1);
+ end;
@.no font selected@>
set_virtual_char(cur_font,p);
h:=h+@<Width of character |p| in font |cur_font|@>;
diff --git a/Build/source/texk/web2c/lib/texmfmp.c b/Build/source/texk/web2c/lib/texmfmp.c
index acc6fddc4fd..2dd6b09805c 100644
--- a/Build/source/texk/web2c/lib/texmfmp.c
+++ b/Build/source/texk/web2c/lib/texmfmp.c
@@ -88,7 +88,7 @@
#define edit_var "MFEDIT"
#endif /* MF */
#ifdef MP
-#define BANNER "This is MetaPost, Version 1.002"
+#define BANNER "This is MetaPost, Version 1.003"
#define COPYRIGHT_HOLDER "AT&T Bell Laboratories"
#define AUTHOR "John Hobby.\nCurrent maintainer of MetaPost: Taco Hoekwater"
#define PROGRAM_HELP MPHELP
diff --git a/Build/source/texk/web2c/metapost.mk b/Build/source/texk/web2c/metapost.mk
index 11c54e6cd2d..858a97256e2 100644
--- a/Build/source/texk/web2c/metapost.mk
+++ b/Build/source/texk/web2c/metapost.mk
@@ -7,7 +7,8 @@
Makefile: metapost.mk
-metapost = mpost dvitomp
+mpost = mpost
+metapost = $(mpost) dvitomp
mpostdir = mpdir
# mpware is the subdirectory.
diff --git a/Build/source/texk/web2c/mp.ch b/Build/source/texk/web2c/mp.ch
index cf5119f4042..0d914ee9a4f 100644
--- a/Build/source/texk/web2c/mp.ch
+++ b/Build/source/texk/web2c/mp.ch
@@ -356,6 +356,7 @@ end;
@x [3.27] Do file closing in C.
@ Files can be closed with the \ph\ routine `|close(f)|', which
+@:PASCAL H}{\ph@>
@^system dependencies@>
should be used when all input or output with respect to |f| has been completed.
This makes |f| available to be opened again, if desired; and if |f| was used for
@@ -429,6 +430,7 @@ We define |input_ln| in C, for efficiency. Nevertheless we quote the module
@x [3.32] We don't need to open the terminal files.
@ Here is how to open the terminal files
in \ph. The `\.{/I}' switch suppresses the first |get|.
+@:PASCAL H}{\ph@>
@^system dependencies@>
@d t_open_in==reset(term_in,'TTY:','/O/I') {open the terminal for text input}
@@ -443,6 +445,7 @@ any command line arguments the user has provided. It's defined in C.
@x [3.33] Flushing output.
these operations can be specified in \ph:
+@:PASCAL H}{\ph@>
@^system dependencies@>
@d update_terminal == break(term_out) {empty the terminal output buffer}
diff --git a/Build/source/texk/web2c/mp.web b/Build/source/texk/web2c/mp.web
index 26dc205e7fa..c10e52be91e 100644
--- a/Build/source/texk/web2c/mp.web
+++ b/Build/source/texk/web2c/mp.web
@@ -97,8 +97,8 @@ undergoes any modifications, so that it will be clear which version of
@^extensions to \MP@>
@^system dependencies@>
-@d banner=='This is MetaPost, Version 1.002' {printed when \MP\ starts}
-@d metapost_version=="1.002"
+@d banner=='This is MetaPost, Version 1.003' {printed when \MP\ starts}
+@d metapost_version=="1.003"
@ Different \PASCAL s have slightly different conventions, and the present
@!@:PASCAL H}{\ph@>
@@ -149,6 +149,7 @@ portions of the program heading.
Actually the heading shown here is not quite normal: The |program| line
does not mention any |output| file, because \ph\ would ask the \MP\ user
to specify a file name if |output| were specified here.
+@:PASCAL H}{\ph@>
@^system dependencies@>
@d mtype==t@&y@&p@&e {this is a \.{WEB} coding trick:}
@@ -235,6 +236,7 @@ directives shown below specify full checking and inclusion of the \PASCAL\
debugger when \MP\ is being debugged, but they cause range checking and other
redundant code to be eliminated when the production system is being generated.
Arithmetic overflow will be detected in all cases.
+@:PASCAL H}{\ph@>
@^system dependencies@>
@^Overflow in arithmetic@>
@@ -270,6 +272,7 @@ if the compiler wants one. (Of course, if no default mechanism is
available, the |case| statements of \MP\ will have to be laboriously
extended by listing all remaining cases. People who are stuck with such
\PASCAL s have, in fact, done this, successfully but not happily!)
+@:PASCAL H}{\ph@>
@d othercases == others: {default for cases not listed explicitly}
@d endcases == @+end {follows the default case in an extended |case| statement}
@@ -738,6 +741,7 @@ begin rewrite(f,name_of_file,'/O'); w_open_out:=rewrite_OK(f);
end;
@ Files can be closed with the \ph\ routine `|close(f)|', which
+@:PASCAL H}{\ph@>
@^system dependencies@>
should be used when all input or output with respect to |f| has been completed.
This makes |f| available to be opened again, if desired; and if |f| was used for
@@ -843,6 +847,7 @@ is considered an output file the file variable is |term_out|.
@ Here is how to open the terminal files
in \ph. The `\.{/I}' switch suppresses the first |get|.
+@:PASCAL H}{\ph@>
@^system dependencies@>
@d t_open_in==reset(term_in,'TTY:','/O/I') {open the terminal for text input}
@@ -860,6 +865,7 @@ issue an unexpected error message). The third, |wake_up_terminal|,
is supposed to revive the terminal if the user has disabled it by
some instruction to the operating system. The following macros show how
these operations can be specified in \ph:
+@:PASCAL H}{\ph@>
@^system dependencies@>
@d update_terminal == break(term_out) {empty the terminal output buffer}
@@ -995,6 +1001,7 @@ integers lie in the range |-128..127|. To accommodate such systems
we access the string pool via macros that can easily be redefined.
When accessing character dimensions for the \&{infont} operator, an explicit
offset is used to convert from |pool_ASCII_code| to |ASCII_code|.
+@^system dependencies@>
@d si(#) == # {convert from |ASCII_code| to |pool_ASCII_code|}
@d so(#) == # {convert from |pool_ASCII_code| to |ASCII_code|}
@@ -1356,11 +1363,8 @@ on the information that \.{WEB} has output while processing \MP.
@p @!init function get_strings_started:boolean; {initializes the string pool,
but returns |false| if something goes wrong}
label done,exit;
-var @!k,@!l:0..255; {small indices or counters}
-@!m,@!n:text_char; {characters input from |pool_file|}
+var @!k:0..255; {small indices or counters}
@!g:str_number; {garbage}
-@!a:integer; {accumulator for check sum}
-@!c:boolean; {check sum has been checked}
begin pool_ptr:=0; str_ptr:=0; max_pool_ptr:=0; max_str_ptr:=0;
str_start[0]:=0;
next_str[0]:=1;
@@ -2211,6 +2215,7 @@ or zero.
desirable to avoid producing multiple error messages in case of arithmetic
overflow. So the routines below set the global variable |arith_error| to |true|
instead of reporting errors directly to the user.
+@^overflow in arithmetic@>
@<Glob...@>=
@!arith_error:boolean; {has arithmetic overflow occurred recently?}
@@ -2444,7 +2449,7 @@ var @!p:integer; {the fraction so far}
@!negative:boolean; {should the result be negated?}
@!n:integer; {additional multiple of $q$}
@!be_careful:integer; {disables certain compiler optimizations}
-begin @<Reduce to the case that |f>=0| and |q>0|@>;
+begin @<Reduce to the case that |f>=0| and |q>=0|@>;
if f<fraction_one then n:=0
else begin n:=f div fraction_one; f:=f mod fraction_one;
if q<=el_gordo div n then n:=n*q
@@ -2461,7 +2466,7 @@ if negative then take_fraction:=-(n+p)
else take_fraction:=n+p;
end;
-@ @<Reduce to the case that |f>=0| and |q>0|@>=
+@ @<Reduce to the case that |f>=0| and |q>=0|@>=
if f>=0 then negative:=false
else begin negate(f); negative:=true;
end;
@@ -2500,7 +2505,7 @@ var @!p:integer; {the fraction so far}
@!negative:boolean; {should the result be negated?}
@!n:integer; {additional multiple of $q$}
@!be_careful:integer; {disables certain compiler optimizations}
-begin @<Reduce to the case that |f>=0| and |q>0|@>;
+begin @<Reduce to the case that |f>=0| and |q>=0|@>;
if f<unity then n:=0
else begin n:=f div unity; f:=f mod unity;
if q<=el_gordo div n then n:=n*q
@@ -3043,8 +3048,8 @@ fourth_octant:n_arg:=one_eighty_deg-z;
fifth_octant:n_arg:=z-one_eighty_deg;
sixth_octant:n_arg:=-z-ninety_deg;
seventh_octant:n_arg:=z-ninety_deg;
-eighth_octant:n_arg:=-z;
-end {there are no other cases}
+othercases n_arg:=-z; { |eighth_octant| }
+end
@ At this point we have |x>=y>=0|, and |x>0|. The numbers are scaled up
or down until $2^{28}\L x<2^{29}$, so that accurate fixed-point calculations
@@ -3406,7 +3411,7 @@ relevant size when a node is freed. Locations greater than or equal to
\.{AVAIL} stack is used for allocation in this region.
Locations of |mem| between |mem_min| and |mem_top| may be dumped as part
-of preloaded format files, by the \.{INIMP} preprocessor.
+of preloaded mem files, by the \.{INIMP} preprocessor.
@.INIMP@>
Production versions of \MP\ may extend the memory at the top end in order to
provide more space; these locations, between |mem_top| and |mem_max|,
@@ -3684,7 +3689,6 @@ appear in locations |hi_mem_stat_min| through |mem_top|, inclusive.
when \MP\ is initializing itself the slow way.
@<Initialize table entries (done by \.{INIMP} only)@>=
-@^data structure assumptions@>
rover:=lo_mem_stat_max+1; {initialize the dynamic memory}
link(rover):=empty_flag;
node_size(rover):=1000; {which is a 1000-word available node}
@@ -3921,7 +3925,7 @@ At any rate, here is the list, for future reference.
@d mpx_break=3 {stop reading an \.{MPX} file (\&{mpxbreak})}
@d max_pre_command=mpx_break
@d if_test=4 {conditional text (\&{if})}
-@d fi_or_else=5 {delimiters for conditionals (\&{elseif}, \&{else}, \&{fi}}
+@d fi_or_else=5 {delimiters for conditionals (\&{elseif}, \&{else}, \&{fi})}
@d input=6 {input a source file (\&{input}, \&{endinput})}
@d iteration=7 {iterate (\&{for}, \&{forsuffixes}, \&{forever}, \&{endfor})}
@d repeat_loop=8 {special command substituted for \&{endfor}}
@@ -3950,7 +3954,7 @@ At any rate, here is the list, for future reference.
@d special_command=30 {output special info (\&{special})
or font map info (\&{fontmapfile}, \&{fontmapline})}
@d write_command=31 {write text to a file (\&{write})}
-@d type_name=32 {declare a type (\&{numeric}, \&{pair}, etc.}
+@d type_name=32 {declare a type (\&{numeric}, \&{pair}, etc.)}
@d max_statement_command=type_name
@d min_primary_command=type_name
@d left_delimiter=33 {the left delimiter of a matching pair}
@@ -4006,7 +4010,7 @@ At any rate, here is the list, for future reference.
@d until_token=73 {the operator `\&{until}'}
@d within_token=74 {the operator `\&{within}'}
@d lig_kern_token=75
- {the operators `\&{kern}' and `\.{=:}' and `\.{=:\char'174}, etc.}
+ {the operators `\&{kern}' and `\.{=:}' and `\.{=:\char'174}', etc.}
@d assignment=76 {the operator `\.{:=}'}
@d skip_to=77 {the operation `\&{skipto}'}
@d bchar_label=78 {the operator `\.{\char'174\char'174:}'}
@@ -4358,7 +4362,7 @@ fuss with. Every such parameter has an identifying code number, defined here.
@d tracing_lost_chars=11 {show characters that aren't \&{infont}}
@d tracing_online=12 {show long diagnostics on terminal and in the log file}
@d year=13 {the current year (e.g., 1984)}
-@d month=14 {the current month (e.g, 3 $\equiv$ March)}
+@d month=14 {the current month (e.g., 3 $\equiv$ March)}
@d day=15 {the current day of the month}
@d time=16 {the number of minutes past midnight when this job started}
@d char_code=17 {the number of the next character to be output}
@@ -5224,9 +5228,8 @@ present, we shall refer to the |info| field of this special node as the
@^reference counts@>
The next node or nodes after the reference count serve to describe the
-formal parameters. They either contain a code word that specifies all
-of the parameters, or they contain zero or more parameter tokens followed
-by the code `|general_macro|'.
+formal parameters. They consist of zero or more parameter tokens followed
+by a code for the type of macro.
@d ref_count==info
{reference count preceding a macro definition or picture header}
@@ -5281,7 +5284,7 @@ exit:end;
The variables of \MP\ programs can be simple, like `\.x', or they can
combine the structural properties of arrays and records, like `\.{x20a.b}'.
A \MP\ user assigns a type to a variable like \.{x20a.b} by saying, for
-example, `\.{boolean} \.{x20a.b}'. It's time for us to study how such
+example, `\.{boolean} \.{x[]a.b}'. It's time for us to study how such
things are represented inside of the computer.
Each variable value occupies two consecutive words, either in a two-word
@@ -5326,7 +5329,8 @@ final attribute node links to the constant |end_attr|, whose |attr_loc|
field is greater than any legal hash address. The |attr_head| in the
parent points to a node whose |name_type| is |structured_root|; this
node represents the null attribute, i.e., the variable that is relevant
-when no attributes are attached to the parent. The |attr_head| node is either
+when no attributes are attached to the parent. The |attr_head| node
+has the fields of either
a value node, a subscript node, or an attribute node, depending on what
the parent would be if it were not structured; but the subscript and
attribute fields are ignored, so it effectively contains only the data of
@@ -5365,9 +5369,10 @@ a pencil to draw a diagram.) The lone variable `\.x' is represented by
to an attribute node representing `\.{x[]}'. Thus |name_type(q1)=attr|,
|attr_loc(q1)=collective_subscript=0|, |parent(q1)=p|,
|type(q1)=structured|, |attr_head(q1)=qq|, and |subscr_head(q1)=qq1|;
-|qq| is a value node with |type(qq)=numeric_type| (assuming that \.{x5} is
-numeric, because |qq| represents `\.{x[]}' with no further attributes),
-|name_type(qq)=structured_root|, and
+|qq| is a three-word ``attribute-as-value'' node with |type(qq)=numeric_type|
+(assuming that \.{x5} is numeric, because |qq| represents `\.{x[]}'
+with no further attributes), |name_type(qq)=structured_root|,
+|attr_loc(qq)=0|, |parent(qq)=p|, and
|link(qq)=qq1|. (Now pay attention to the next part.) Node |qq1| is
an attribute node representing `\.{x[][]}', which has never yet
occurred; its |type| field is |undefined|, and its |value| field is
@@ -5603,7 +5608,8 @@ place in the structure. Node~|p| itself does not move, nor are its
@p function new_structure(@!p:pointer):pointer;
var @!q,@!r:pointer; {list manipulation registers}
-begin case name_type(p) of
+begin r:=null;
+case name_type(p) of
root: begin q:=link(p); r:=get_node(value_node_size); equiv(q):=r;
end;
subscr: @<Link a new subscript node |r| in place of node |p|@>;
@@ -5842,8 +5848,8 @@ path_type,unknown_path:und_type:=unknown_path;
picture_type,unknown_picture:und_type:=unknown_picture;
transform_type,color_type,cmykcolor_type,
pair_type,numeric_type:und_type:=type(p);
-known,dependent,proto_dependent,independent:und_type:=numeric_type;
-end; {there are no other cases}
+othercases und_type:=numeric_type; { |known,dependent,proto_dependent,independent| }
+end;
end;
@ The |clear_symbol| routine is used when we want to redefine the equivalent
@@ -5860,7 +5866,7 @@ defined_macro,secondary_primary_macro,tertiary_secondary_macro,
tag_token:if q<>null then
if saving then name_type(q):=saved_root
else begin flush_below_variable(q); free_node(q,value_node_size);
- end;
+ end;@;
othercases do_nothing
endcases;@/
eqtb[p]:=eqtb[frozen_undefined];
@@ -5886,7 +5892,7 @@ until the most recent such entry has been removed.
\smallskip\hang
|info(p)=q|, where |1<=q<=hash_end|, means that |mem[p+1]| holds the former
contents of |eqtb[q]|. Such save stack entries are generated by \&{save}
-commands or suitable \&{interim} commands.
+commands.
\smallskip\hang
|info(p)=hash_end+q|, where |q>0|, means that |value(p)| is a |scaled|
@@ -6044,7 +6050,7 @@ the knot, and to \\{left} fields instead of \\{right} fields.
Non-|explicit| control points will be chosen based on ``tension'' parameters
in the |left_tension| and |right_tension| fields. The
`\&{atleast}' option is represented by negative tension values.
-@!@:at_least_}{\&{atleast} primitive@>
+@:at_least_}{\&{atleast} primitive@>
For example, the \MP\ path specification
$$\.{z0..z1..tension atleast 1..\{curl 2\}z2..z3\{-1,-2\}..tension
@@ -6181,9 +6187,6 @@ if (left_type(p)<>explicit)and(left_type(p)<>open) then
@ A curl of 1 is shown explicitly, so that the user sees clearly that
\MP's default curl is present.
-The code here uses the fact that |left_curl==left_given| and
-|right_curl==right_given|.
-
@<Print information for a curve that begins |curl|...@>=
begin if left_type(p)=open then print("??"); {can't happen}
@.??@>
@@ -6453,7 +6456,7 @@ have been given for $0<k<n$, and it will be convenient to introduce
equations of the same form for $k=0$ and $k=n$, where
$$A_0=B_0=C_n=D_n=0.$$
If $\theta_0$ is supposed to have a given value $E_0$, we simply
-define $C_0=0$, $D_0=0$, and $R_0=E_0$. Otherwise a curl
+define $C_0=1$, $D_0=0$, and $R_0=E_0$. Otherwise a curl
parameter, $\gamma_0$, has been specified at~$z_0$; this means
that the mock curvature at $z_0$ should be $\gamma_0$ times the
mock curvature at $z_1$; i.e.,
@@ -6610,7 +6613,7 @@ label found,exit;
var @!k:0..path_size; {current knot number}
@!r,@!s,@!t:pointer; {registers for list traversal}
@<Other local variables for |solve_choices|@>@;
-begin k:=0; s:=p;
+begin k:=0; r:=null; s:=p;
loop@+ begin t:=link(s);
if k=0 then @<Get the linear equations started; or |return|
with the control points in place, if linear equations
@@ -6621,9 +6624,9 @@ loop@+ begin t:=link(s);
adjusted to equal $\theta_0$, if a cycle has ended@>;
curl:@<Set up equation for a curl at $\theta_n$
and |goto found|@>;
- given:@<Calculate the given value of $\theta_n$
- and |goto found|@>;
- end; {there are no other cases}
+ othercases { |given:| }
+ @<Calculate the given value of $\theta_n$ and |goto found|@>;
+ end;
r:=s; s:=t; incr(k);
end;
found:@<Finish choosing angles and assigning control points@>;
@@ -6873,7 +6876,6 @@ end;
$\\{ss}\L\sin\theta\,/\sin(\theta+\phi)$ are to be enforced if $\sin\theta$,
$\sin\phi$, and $\sin(\theta+\phi)$ all have the same sign. Otherwise
there is no ``bounding triangle.''
-@!@:at_least_}{\&{atleast} primitive@>
@<Decrease the velocities, if necessary...@>=
if((st>=0)and(sf>=0))or((st<=0)and(sf<=0)) then
@@ -8519,13 +8521,21 @@ end
case type(p) of
start_clip_code,start_bounds_code: path_p(pp):=copy_path(path_p(p));
fill_code: begin path_p(pp):=copy_path(path_p(p));
+ if pre_script(p)<>null then add_str_ref(pre_script(pp));
+ if post_script(p)<>null then add_str_ref(post_script(pp));
if pen_p(p)<>null then pen_p(pp):=copy_pen(pen_p(p));
end;
stroked_code: begin path_p(pp):=copy_path(path_p(p));
+ if pre_script(p)<>null then add_str_ref(pre_script(pp));
+ if post_script(p)<>null then add_str_ref(post_script(pp));
pen_p(pp):=copy_pen(pen_p(p));
if dash_p(p)<>null then add_edge_ref(dash_p(pp));
end;
-text_code: add_str_ref(text_p(pp));
+text_code: begin
+ if pre_script(p)<>null then add_str_ref(pre_script(pp));
+ if post_script(p)<>null then add_str_ref(post_script(pp));
+ add_str_ref(text_p(pp));
+ end;
stop_clip_code,stop_bounds_code: do_nothing;
end {there are no other cases}
@@ -8753,7 +8763,7 @@ var @!p:pointer; {this scans the stroked nodes in the object list}
@!d,@!dd:pointer; {pointers used to create the dash list}
@<Other local variables in |make_dashes|@>@;
begin if dash_list(h)<>null_dash then goto found;
-p0:=null;
+p0:=null; y0:=0;
p:=link(dummy_loc(h));
while p<>null do
begin if type(p)<>stroked_code then
@@ -9231,7 +9241,7 @@ spec_offset:integer; {number of pen edges between |h| and the initial offset}
function offset_prep(@!c,@!h:pointer):pointer;
label not_found;
var @!n:halfword; {the number of vertices in the pen polygon}
-@!p,@!q,@!r,@!w,@!ww:pointer; {for list manipulation}
+@!p,@!q,@!q0,@!c0,@!r,@!w,@!ww:pointer; {for list manipulation}
@!k_needed:integer; {amount to be added to |info(p)| when it is computed}
@!w0:pointer; {a pointer to pen offset to use just before |p|}
@!dxin,@!dyin:scaled; {the direction into knot |p|}
@@ -9239,7 +9249,7 @@ var @!n:halfword; {the number of vertices in the pen polygon}
@<Other local variables for |offset_prep|@>@;
begin @<Initialize the pen size~|n|@>;
@<Initialize the incoming direction and pen offset at |c|@>;
-p:=c; k_needed:=0;
+p:=c; c0:=c; k_needed:=0;
repeat q:=link(p);
@<Split the cubic between |p| and |q|, if necessary, into cubics
associated with single offsets, after which |q| should
@@ -9284,20 +9294,26 @@ w0:=h
@ We must be careful not to remove the only cubic in a cycle.
But we must also be careful for another reason. If the user-supplied
-path starts with a set of degenerate cubics, these should not be removed
-because at this point we cannot do so cleanly. The relevant bug is
-tracker id 267, bugs 52c, reported by Boguslav.
+path starts with a set of degenerate cubics, the target node |q| can
+be collapsed to the initial node |p| which might be the same as the
+initial node |c| of the curve. This would cause the |offset_prep| routine
+to bail out too early, causing distress later on. (See for example
+the testcase reported by Bogus\l{}aw Jackowski in tracker id 267, case 52c
+on Sarovar.)
@<Advance |p| to node |q|, removing any ``dead'' cubics...@>=
+q0:=q;
repeat r:=link(p);
if x_coord(p)=right_x(p) then if y_coord(p)=right_y(p) then
if x_coord(p)=left_x(r) then if y_coord(p)=left_y(r) then
if x_coord(p)=x_coord(r) then if y_coord(p)=y_coord(r) then
- if r<>p then if ((r<>q) or (originator(r)<>metapost_user)) then
+ if r<>p then
@<Remove the cubic following |p| and update the data structures
to merge |r| into |p|@>;
p:=r;
-until p=q
+until p=q;
+{ Check if we removed too much }
+if (q<>q0) and ((q<>c) or (c=c0)) then q:=link(q)
@ @<Remove the cubic following |p| and update the data structures...@>=
begin k_needed:=info(p)-zero_off;
@@ -9407,6 +9423,7 @@ represent $Y_0=2^l(y_1-y_0)$, $Y_1=2^l(y_2-y_1)$, and $Y_2=2^l(y_3-y_2)$.
@!s:fraction; {a temporary value}
@ @<Prepare for derivative computations...@>=
+dx0:=0; dy0:=0;
x0:=right_x(p)-x_coord(p);
x2:=x_coord(q)-left_x(q);
x1:=left_x(q)-right_x(p);
@@ -9481,7 +9498,7 @@ begins to fail.
@<Compute test coefficients |(t0,t1,t2)| for $d(t)$ versus...@>=
du:=x_coord(ww)-x_coord(w); dv:=y_coord(ww)-y_coord(w);
-if abs(du)>=abs(dv) then
+if abs(du)>=abs(dv) then {$s_{k-1}\le1$ or $s_k\le1$}
begin s:=make_fraction(dv,du);
t0:=take_fraction(x0,s)-y0;
t1:=take_fraction(x1,s)-y1;
@@ -9497,7 +9514,8 @@ else begin s:=make_fraction(du,dv);
if t0<0 then t0:=0 {should be positive without rounding error}
@ The curve has crossed $d_k$ or $d_{k-1}$; its initial segment satisfies
-$(*)$, and it might cross again, yielding another solution of $(*)$.
+$(*)$, and it might cross again and return towards $s_{k-1}$ or $s_k$,
+respectively, yielding another solution of $(*)$.
@<Split the cubic at $t$, and split off another...@>=
begin split_cubic(p,t); p:=link(p); info(p):=zero_off+rise;
@@ -9691,6 +9709,8 @@ the path should always change the sign of |turn_amt|.
@<Decide on the net change in pen offsets and set |turn_amt|@>=
d_sign:=ab_vs_cd(dx,dyin, dxin,dy);
if d_sign=0 then
+ @<Check rotation direction based on node position@>;
+if d_sign=0 then
if dx=0 then
if dy>0 then d_sign:=1 @+else d_sign:=-1
else if dx>0 then d_sign:=1 @+else d_sign:=-1;
@@ -9699,6 +9719,19 @@ if d_sign=0 then
turn_amt:=get_turn_amt(w, dxin, dyin, d_sign>0);
if ss<0 then turn_amt:=turn_amt-d_sign*n
+@ We check rotation direction by looking at the vector connecting the current
+node with the next. If its angle with incoming and outgoing tangents has the
+same sign, we pick this as |d_sign|, since it means we have a flex, not a cusp.
+Otherwise we proceed to the cusp code.
+
+@<Check rotation direction based on node position@>=
+begin
+u0:=x_coord(q)-x_coord(p);
+u1:=y_coord(q)-y_coord(p);
+d_sign:=half(ab_vs_cd(dx, u1, u0, dy)+ab_vs_cd(u0, dyin, dxin, u1));
+end
+
+
@ In order to be invariant under path reversal, the result of this computation
should not change when |x0|, |y0|, $\ldots$ are all negated and |(x0,y0)| is
then swapped with |(x2,y2)|. We make use of the identities
@@ -9805,6 +9838,7 @@ repeat q:=link(p); q0:=q;
qx:=x_coord(q); qy:=y_coord(q);
k:=info(q);@/
k0:=k; w0:=w;
+dxin:=0;
if k<>zero_off then
@<Set |join_type| to indicate how to handle offset changes at~|q|@>;
@<Add offset |w| to the cubic from |p| to |q|@>;
@@ -9832,6 +9866,7 @@ degenerate cubic. Setting |join_type:=2| in this case makes the computed
envelope degenerate as well.
@<Set |join_type| to indicate how to handle offset changes at~|q|@>=
+dxin:=0; dyin:=0; dxout:=0; dyout:=0; join_type:=0;
if k<zero_off then join_type:=2
else begin if (q<>spec_p1)and(q<>spec_p2) then join_type:=ljoin
else if lcap=2 then join_type:=3
@@ -10101,7 +10136,7 @@ else begin y:=make_fraction(y,abs(x));
end
@ Since we're interested in the tangent directions, we work with the
-derivative $${\textstyle1\over3}B'(x_0,x_1,x_2,x_3;t)=
+derivative $${1\over3}B'(x_0,x_1,x_2,x_3;t)=
B(x_1-x_0,x_2-x_1,x_3-x_2;t)$$ instead of
$B(x_0,x_1,x_2,x_3;t)$ itself. The derived coefficients are also scaled up
in order to achieve better accuracy.
@@ -10271,7 +10306,7 @@ overlap if and only if $u\submin\L x\submax$ and
$x\submin\L u\submax$. Letting
$$U\submin=\min(0,U_1,U_1+U_2,U_1+U_2+U_3),\;
U\submax=\max(0,U_1,U_1+U_2,U_1+U_2+U_3),$$
-we have $u\submin=2^lu_0+U\submin$, etc.; the condition for overlap
+we have $2^lu\submin=2^lu_0+U\submin$, etc.; the condition for overlap
reduces to
$$X\submin-U\submax\L 2^l(u_0-x_0)\L X\submax-U\submin.$$
Thus we want to maintain the quantity $2^l(u_0-x_0)$; similarly,
@@ -10478,13 +10513,14 @@ split |cubic_intersection| up into two procedures.
@<Glob...@>=
@!delx,@!dely:integer; {the components of $\Delta=2^l(w_0-z_0)$}
-@!tol:integer; {bound on the uncertainly in the overlap test}
+@!tol:integer; {bound on the uncertainty in the overlap test}
@!uv,@!xy:0..bistack_size; {pointers to the current packets of interest}
@!three_l:integer; {|tol_step| times the bisection level}
@!appr_t,@!appr_tt:integer; {best approximations known to the answers}
@ We shall assume that the coordinates are sufficiently non-extreme that
integer overflow will not occur.
+@^overflow in arithmetic@>
@<Initialize for intersections at level zero@>=
q:=link(p); qq:=link(pp); bisect_ptr:=int_packets;@/
@@ -10535,8 +10571,8 @@ not_found: if odd(cur_tt) then
+stack_3(u_packet(uv));
dely:=dely+stack_1(v_packet(uv))+stack_2(v_packet(uv))
+stack_3(v_packet(uv));
- uv:=uv+int_packets; {switch from |l_packet| to |r_packet|}
- decr(cur_tt); xy:=xy-int_packets; {switch from |r_packet| to |l_packet|}
+ uv:=uv+int_packets; {switch from |l_packets| to |r_packets|}
+ decr(cur_tt); xy:=xy-int_packets; {switch from |r_packets| to |l_packets|}
delx:=delx+stack_1(x_packet(xy))+stack_2(x_packet(xy))
+stack_3(x_packet(xy));
dely:=dely+stack_1(y_packet(xy))+stack_2(y_packet(xy))
@@ -10547,7 +10583,7 @@ else begin incr(cur_tt); tol:=tol+three_l;
-stack_3(x_packet(xy));
dely:=dely-stack_1(y_packet(xy))-stack_2(y_packet(xy))
-stack_3(y_packet(xy));
- xy:=xy+int_packets; {switch from |l_packet| to |r_packet|}
+ xy:=xy+int_packets; {switch from |l_packets| to |r_packets|}
end
@ @<Descend to the previous level...@>=
@@ -10646,11 +10682,10 @@ The next patch detects overflow of independent-variable serial
numbers. Diagnosed and patched by Thorsten Dahlheimer.
@d s_scale=64 {the serial numbers are multiplied by this factor}
-@d max_indep_vars==@'177777777 {$2^{25}-1$}
-@d max_serial_no==@'17777777700 {|max_indep_vars*s_scale|}
@d new_indep(#)== {create a new independent variable}
- begin if serial_no=max_serial_no then
- overflow("independent variables",max_indep_vars);
+ begin if serial_no>el_gordo-s_scale then
+ overflow("independent variables",serial_no div s_scale);
+@:METAPOST capacity exceeded independent variables}{\quad independent variables@>
type(#):=independent; serial_no:=serial_no+s_scale;
value(#):=serial_no;
end
@@ -12320,8 +12355,8 @@ fin_numeric_token:@<Pack the numeric and fraction parts of a numeric token
found: cur_sym:=id_lookup(k,loc-k);
end
-@ We go to |restart| instead of to |switch|, because |state| might equal
-|token_list| after the error has been dealt with
+@ We go to |restart| instead of to |switch|, because we might enter
+|token_state| after the error has been dealt with
(cf.\ |clear_for_error_prompt|).
@<Decry the invalid...@>=
@@ -12728,7 +12763,7 @@ it makes sense to have most of the work done by a single subroutine. That
subroutine is called |scan_toks|.
The first parameter to |scan_toks| is the command code that will
-terminate scanning (either |macro_def|, |loop_repeat|, or |iteration|).
+terminate scanning (either |macro_def| or |iteration|).
The second parameter, |subst_list|, points to a (possibly empty) list
of two-word nodes whose |info| and |value| fields specify symbol tokens
@@ -13258,6 +13293,7 @@ var @!r:pointer; {current node in the macro's token list}
@!l_delim,@!r_delim:pointer; {a delimiter pair}
@!tail:pointer; {tail of the argument list}
begin r:=link(def_ref); add_mac_ref(def_ref);
+tail:=null; l_delim:=null; r_delim:=null;
if arg_list=null then n:=0
else @<Determine the number |n| of arguments already supplied,
and set |tail| to the tail of |arg_list|@>;
@@ -13384,7 +13420,7 @@ if (cur_cmd<>right_delimiter)or(cur_mod<>l_delim) then
back_error;
end
-@ A \&{suffix} or \&{text} parameter will be have been scanned as
+@ A \&{suffix} or \&{text} parameter will have been scanned as
a token list pointed to by |cur_exp|, in which case we will have
|cur_type=token_list|.
@@ -14044,7 +14080,7 @@ of three system-dependent
procedures called |begin_name|, |more_name|, and |end_name|. In
essence, if the user-specified characters of the file name are $c_1\ldots c_n$,
the system-independent driver program does the operations
-$$|begin_name|;\,|more_name|(c_1);\,\ldots\,;|more_name|(c_n);
+$$|begin_name|;\,|more_name|(c_1);\,\ldots\,;\,|more_name|(c_n);
\,|end_name|.$$
These three procedures communicate with each other via global variables.
Afterwards the file name will appear in the string pool as three strings
@@ -14718,8 +14754,8 @@ or |false_code|.
\smallskip\hang
|cur_type=unknown_boolean| means that |cur_exp| points to a capsule
-node that is in the ring of variables equivalent
-to at least one undefined boolean variable.
+node that is in
+a ring of equivalent booleans whose value has not yet been defined.
\smallskip\hang
|cur_type=string_type| means that |cur_exp| is a string number (i.e., an
@@ -14728,8 +14764,8 @@ includes this particular reference.
\smallskip\hang
|cur_type=unknown_string| means that |cur_exp| points to a capsule
-node that is in the ring of variables equivalent
-to at least one undefined string variable.
+node that is in
+a ring of equivalent strings whose value has not yet been defined.
\smallskip\hang
|cur_type=pen_type| means that |cur_exp| points to a node in a pen. Nobody
@@ -14738,8 +14774,8 @@ elliptical.
\smallskip\hang
|cur_type=unknown_pen| means that |cur_exp| points to a capsule
-node that is in the ring of variables equivalent
-to at least one undefined pen variable.
+node that is in
+a ring of equivalent pens whose value has not yet been defined.
\smallskip\hang
|cur_type=path_type| means that |cur_exp| points to a the first node of
@@ -14748,8 +14784,8 @@ the path will have been chosen.
\smallskip\hang
|cur_type=unknown_path| means that |cur_exp| points to a capsule
-node that is in the ring of variables equivalent
-to at least one undefined path variable.
+node that is in
+a ring of equivalent paths whose value has not yet been defined.
\smallskip\hang
|cur_type=picture_type| means that |cur_exp| points to an edge header node.
@@ -14758,8 +14794,8 @@ contains a reference count that includes this particular reference.
\smallskip\hang
|cur_type=unknown_picture| means that |cur_exp| points to a capsule
-node that is in the ring of variables equivalent
-to at least one undefined picture variable.
+node that is in
+a ring of equivalent pictures whose value has not yet been defined.
\smallskip\hang
|cur_type=transform_type| means that |cur_exp| points to a |transform_type|
@@ -14806,8 +14842,7 @@ example, in the expression
\smallskip\hang
|cur_type=token_list| means that |cur_exp| points to a linked list of
-tokens. This case arises only on the left-hand side of an assignment
-(`\.{:=}') operation, under very special circumstances.
+tokens.
\smallskip\noindent
The possible settings of |cur_type| have been listed here in increasing
@@ -14817,9 +14852,9 @@ are allowed. Conversely, \MP\ has no variables of type |vacuous| or
|token_list|.
@ Capsules are two-word nodes that have a similar meaning
-to |cur_type| and |cur_exp|. Such nodes have |name_type=capsule|
-and |link<=void|; and their |type| field is one of the possibilities for
-|cur_type| listed above.
+to |cur_type| and |cur_exp|. Such nodes have |name_type=capsule|,
+and their |type| field is one of the possibilities for |cur_type| listed above.
+Also |link<=void| in capsules that aren't part of a token list.
The |value| field of a capsule is, in most cases, the value that
corresponds to its |type|, as |cur_exp| corresponds to |cur_type|.
@@ -14904,6 +14939,7 @@ output. If it is~0, dependency lists will be abbreviated to
`\.{linearform}' unless they consist of a single term. If it is greater
than~1, complicated structures (pens, pictures, and paths) will be displayed
in full.
+@.linearform@>
@<Declare subroutines for printing expressions@>=
@t\4@>@<Declare the procedure called |print_dp|@>@;
@@ -14916,7 +14952,7 @@ var @!restore_cur_exp:boolean; {should |cur_exp| be restored?}
begin if p<>null then restore_cur_exp:=false
else begin p:=stash_cur_exp; restore_cur_exp:=true;
end;
-t:=type(p);
+t:=type(p); v:=0;
if t<dependent then v:=value(p)@+else if t<independent then v:=dep_list(p);
@<Print an abbreviated value of |v| with format depending on |t|@>;
if restore_cur_exp then unstash_cur_exp(p);
@@ -14976,6 +15012,7 @@ var @!q:pointer; {the node following |p|}
begin q:=link(p);
if (info(q)=null) or (verbosity>0) then print_dependency(p,t)
else print("linearform");
+@.linearform@>
end;
@ The displayed name of a variable in a ring will not be a capsule unless
@@ -15039,7 +15076,7 @@ var @!t:small_number; {a type code}
@!v:integer; {a value}
@!vv:integer; {another value}
@!q,@!r,@!s,@!pp:pointer; {link manipulation registers}
-begin t:=type(p);
+begin t:=type(p); v:=0;
if t<dependent then v:=value(p);
case t of
undefined,vacuous,boolean_type,known,numeric_type:do_nothing;
@@ -15078,7 +15115,7 @@ something depends on it. In the latter case, a dependent variable whose
coefficient of dependence is maximal will take its place.
The relevant algorithm is due to Ignacio~A. Zabala, who implemented it
as part of his Ph.D. thesis (Stanford University, December 1982).
-@^Zabala Salelles, Ignacio Andres@>
+@^Zabala Salelles, Ignacio Andr\'es@>
For example, suppose that variable $x$ is being recycled, and that the
only variables depending on~$x$ are $y=2x+a$ and $z=x+b$. In this case
@@ -15615,7 +15652,8 @@ doesn't bother to update its information about type. And if
@!macro_ref:pointer; {reference count for a suffixed macro}
@ @<Scan a variable primary...@>=
-begin fast_get_avail(pre_head); tail:=pre_head; post_head:=null; tt:=vacuous;
+begin fast_get_avail(pre_head); tail:=pre_head; post_head:=null; tt:=vacuous;
+macro_ref:=null;
loop@+ begin t:=cur_tok; link(tail):=t;
if tt<>undefined then
begin @<Find the approximate type |tt| and corresponding~|q|@>;
@@ -15799,7 +15837,7 @@ numeric_type:begin new_indep(p); goto restart;
end;
independent: begin q:=single_dependency(p);
if q=dep_final then
- begin cur_type:=known; cur_exp:=0; free_node(q,value_node_size);
+ begin cur_type:=known; cur_exp:=0; free_node(q,dep_node_size);
end
else begin cur_type:=dependent; encapsulate(q);
end;
@@ -15845,7 +15883,7 @@ begin if type(q)=known then
else if type(q)=independent then
begin p:=single_dependency(q);
if p=dep_final then
- begin type(r):=known; value(r):=0; free_node(p,value_node_size);
+ begin type(r):=known; value(r):=0; free_node(p,dep_node_size);
end
else begin type(r):=dependent; new_dep(r,p);
end;
@@ -16005,7 +16043,7 @@ var @!p,@!q,@!r,@!pp,@!qq:pointer; {for list manipulation}
@!cycle_hit:boolean; {did a path expression just end with `\&{cycle}'?}
@!x,@!y:scaled; {explicit coordinates or tension at a path join}
@!t:endpoint..open; {knot type following a path join}
-begin my_var_flag:=var_flag;
+begin my_var_flag:=var_flag; t:=endpoint; x:=0; y:=0; mac_name:=null;
restart:if(cur_cmd<min_primary_command)or@|
(cur_cmd>max_primary_command) then
bad_exp("An");
@@ -16225,9 +16263,9 @@ cur_y:=cur_exp; cur_x:=x;
end
@ At this point |right_type(q)| is usually |open|, but it may have been
-set to some other value by a previous splicing operation. We must maintain
-the value of |right_type(q)| in unusual cases such as
-`\.{..z1\{z2\}\&\{z3\}z1\{0,0\}..}'.
+set to some other value by a previous operation. We must maintain
+the value of |right_type(q)| in cases such as
+`\.{..\{curl2\}z\{0,0\}..}'.
@<Put the pre-join...@>=
begin t:=scan_direction;
@@ -16838,7 +16876,12 @@ procedure pair_to_path;
begin cur_exp:=new_knot; cur_type:=path_type;
end;
-@ @<Additional cases of unary operators@>=
+@
+@d pict_color_type(#)==(link(dummy_loc(cur_exp))<>null) and
+ (has_color(link(dummy_loc(cur_exp)))) and
+ (color_model(link(dummy_loc(cur_exp)))=#)
+
+@<Additional cases of unary operators@>=
x_part,y_part:if (cur_type=pair_type)or(cur_type=transform_type) then
take_part(c)
else if cur_type=picture_type then take_pict_part(c)
@@ -16846,15 +16889,20 @@ x_part,y_part:if (cur_type=pair_type)or(cur_type=transform_type) then
xx_part,xy_part,yx_part,yy_part: if cur_type=transform_type then take_part(c)
else if cur_type=picture_type then take_pict_part(c)
else bad_unary(c);
-red_part,green_part,blue_part: if cur_type=color_type then take_part(c)
- else if cur_type=picture_type then take_pict_part(c)
- else bad_unary(c);
-cyan_part,magenta_part,yellow_part,black_part: if cur_type=cmykcolor_type
- then take_part(c) else if cur_type=picture_type then take_pict_part(c)
- else bad_unary(c);
+red_part,green_part,blue_part:
+ if cur_type=color_type then take_part(c)
+ else if cur_type=picture_type then begin
+ if pict_color_type(rgb_model) then take_pict_part(c) else bad_color_part(c);
+ end else bad_unary(c);
+cyan_part,magenta_part,yellow_part,black_part:
+ if cur_type=cmykcolor_type then take_part(c)
+ else if cur_type=picture_type then begin
+ if pict_color_type(cmyk_model) then take_pict_part(c) else bad_color_part(c);
+ end else bad_unary(c);
grey_part: if cur_type=known then cur_exp:=value(c)
- else if cur_type=picture_type then take_pict_part(c)
- else bad_unary(c);
+ else if cur_type=picture_type then begin
+ if pict_color_type(grey_model) then take_pict_part(c) else bad_color_part(c);
+ end else bad_unary(c);
color_model_part: if cur_type=picture_type then take_pict_part(c)
else bad_unary(c);
@@ -16870,6 +16918,33 @@ make_exp_copy(p+sector_offset[c+x_part_sector-x_part]);
recycle_value(temp_val);
end;
+@ @<Declare unary action...@>=
+procedure bad_color_part(@!c:quarterword);
+var @!p:pointer; {the big node}
+begin
+ p:=link(dummy_loc(cur_exp));
+ exp_err("Wrong picture color model: "); print_op(c);
+@.Wrong picture color model...@>
+ if color_model(p)=grey_model then
+ print(" of grey object")
+ else if color_model(p)=cmyk_model then
+ print(" of cmyk object")
+ else if color_model(p)=rgb_model then
+ print(" of rgb object")
+ else if color_model(p)=no_model then
+ print(" of marking object")
+ else
+ print(" of defaulted object");
+ help3("You can only ask for the redpart, greenpart, bluepart of a rgb object,")@/
+ ("the cyanpart, magentapart, yellowpart or blackpart of a cmyk object, ")@/
+ ("or the greypart of a grey object. No mixing and matching, please.");
+ error;
+ if c=black_part then
+ flush_cur_exp(unity)
+ else
+ flush_cur_exp(0);
+end;
+
@ @<Initialize table entries...@>=
name_type(temp_val):=capsule;
@@ -17632,6 +17707,7 @@ argument). The third argument is either |plus| or |minus|.
The sum or difference of the numeric quantities will replace the second
operand. Arithmetic overflow may go undetected; users aren't supposed to
be monkeying around with really big values.
+@^overflow in arithmetic@>
@<Declare binary action...@>=
@t\4@>@<Declare the procedure called |dep_finish|@>@;
@@ -18105,7 +18181,6 @@ to the path~|p|.
@<Declare binary action...@>=
procedure do_path_trans(@!p:pointer);
-label exit;
var @!q:pointer; {list traverser}
begin q:=p;
repeat
@@ -18115,7 +18190,7 @@ if right_type(q)<>endpoint then trans(q+5,q+6); {that's |right_x| and |right_y|}
@^data structure assumptions@>
q:=link(q);
until q=p;
-exit:end;
+end;
@ Transforming a pen is very similar, except that there are no |left_type|
and |right_type| fields.
@@ -18125,7 +18200,6 @@ and |right_type| fields.
@<Declare binary action...@>=
procedure do_pen_trans(@!p:pointer);
-label exit;
var @!q:pointer; {list traverser}
begin if pen_is_elliptical(p) then
begin trans(p+3,p+4); {that's |left_x| and |left_y|}
@@ -18137,7 +18211,7 @@ trans(q+1,q+2); {that's |x_coord| and |y_coord|}
@^data structure assumptions@>
q:=link(q);
until q=p;
-exit:end;
+end;
@ The next transformation procedure applies to edge structures. It will do
any transformation, but the results may be substandard if the picture contains
@@ -18795,7 +18869,7 @@ if cur_type=unknown_path then if type(lhs)=pair_type then
make_eq(lhs); {equate |lhs| to |(cur_type,cur_exp)|}
end;
-@ And |do_assignment| is similar to |do_expression|:
+@ And |do_assignment| is similar to |do_equation|:
@<Declare action procedures for use by |do_statement|@>=
procedure do_assignment;
@@ -18865,7 +18939,7 @@ label restart,done, not_found;
var @!t:small_number; {type of the left-hand side}
@!v:integer; {value of the left-hand side}
@!p,@!q:pointer; {pointers inside of big nodes}
-begin restart: t:=type(lhs);
+begin restart: t:=type(lhs); v:=0;
if t<=pair_type then v:=value(lhs);
case t of
@t\4@>@<For each type |t|, make an equation and |goto done| unless |cur_type|
@@ -18889,7 +18963,7 @@ put_get_error
@ @<For each type |t|, make an equation and |goto done| unless...@>=
boolean_type,string_type,pen_type,path_type,picture_type:
if cur_type=t+unknown_tag then
- begin nonlinear_eq(v,cur_exp,false); goto done;
+ begin nonlinear_eq(v,cur_exp,false); unstash_cur_exp(cur_exp); goto done;
end
else if cur_type=t then
@<Report redundant or inconsistent equation and |goto done|@>;
@@ -19055,7 +19129,7 @@ loop@+ begin get_x_next;
else goto done;
link(t):=get_avail; t:=link(t); info(t):=cur_sym;
end;
-done: if eq_type(x)<>tag_token then clear_symbol(x,false);
+done: if eq_type(x) mod outer_tag<>tag_token then clear_symbol(x,false);
if equiv(x)=null then new_root(x);
scan_declared_variable:=h;
end;
@@ -19445,7 +19519,7 @@ else begin print_char(""""); print(cur_mod); print_char("""");
end
@ The following cases of |print_cmd_mod| might arise in connection
-with |disp_token|, although they don't correspond to any
+with |disp_token|, although they don't necessarily correspond to
primitive tokens.
@<Cases of |print_cmd_...@>=
@@ -19645,7 +19719,7 @@ var @!t:small_number; {|cur_mod| of the |with_option| (should match |cur_type|)}
@!s:str_number; {for string cleanup after combining }
@!cp,@!pp,@!dp,@!ap,@!bp:pointer;
{objects being updated; |void| initially; |null| to suppress update}
-begin cp:=void; pp:=void; dp:=void; ap:=void; bp:=void;
+begin cp:=void; pp:=void; dp:=void; ap:=void; bp:=void; k:=null;
while cur_cmd=with_option do
begin t:=cur_mod;
get_x_next;
@@ -20017,7 +20091,7 @@ any time we call |get_x_next|.
function start_draw_cmd(@!sep:quarterword):pointer;
var @!lhv:pointer; {variable to add to left}
@!add_type:quarterword; {value to be returned in |last_add_type|}
-begin lhv:=null;@/
+begin lhv:=null; add_type:=0;
get_x_next; var_flag:=sep; scan_primary;
if cur_type<>token_list then
@<Abandon edges command because there's no variable@>
@@ -20479,6 +20553,7 @@ since many fonts have a design size equal to one em. The other dimensions
must be less than 16 design-size units in absolute value; thus,
|header[1]| and |param[1]| are the only |fix_word| entries in the whole
\.{TFM} file whose first byte might be something besides 0 or 255.
+@^design size@>
@ Next comes the |char_info| array, which contains one |@!char_info_word|
per character. Each word in this part of the file contains six fields
@@ -20614,6 +20689,7 @@ to help position accents. For example, |slant=.25| means that when you go
up one unit, you also go .25 units to the right. The |slant| is a pure
number; it is the only |fix_word| other than the design size itself that is
not scaled by the design size.
+@^design size@>
\hang|param[2]=space| is the normal spacing between words in text.
Note that character @'40 in the font need not have anything to do with
@@ -20921,7 +20997,7 @@ We may need to cancel skips that span more than 127 lig/kern steps.
@<Process a |skip_to| command and |goto done|@>=
begin c:=get_code;
-if nl-skip_table[c]>128 then {|skip_table[c]<<nl<=undefined_label|}
+if nl-skip_table[c]>128 then
begin skip_error(skip_table[c]); skip_table[c]:=undefined_label;
end;
if skip_table[c]=undefined_label then skip_byte(nl-1):=qi(0)
@@ -21204,6 +21280,7 @@ value(zero_val):=0; info(zero_val):=0;
@ Bytes 5--8 of the header are set to the design size, unless the user has
some crazy reason for specifying them differently.
+@^design size@>
Error messages are not allowed at the time this procedure is called,
so a warning is printed instead.
@@ -21230,7 +21307,7 @@ if header_byte[5]<0 then if header_byte[6]<0 then
header_byte[7]:=(d div 16) mod 256;
header_byte[8]:=(d mod 16)*16;
end;
-max_tfm_dimen:=16*internal[design_size]-internal[design_size] div @'10000000;
+max_tfm_dimen:=16*internal[design_size]-1-internal[design_size] div @'10000000;
if max_tfm_dimen>=fraction_half then max_tfm_dimen:=fraction_half-1;
end;
@@ -21241,9 +21318,9 @@ global variable |tfm_changed| is increased by~one.
@p function dimen_out(@!x:scaled):integer;
begin if abs(x)>max_tfm_dimen then
begin incr(tfm_changed);
- if x>0 then x:=three_bytes-1@+else x:=1-three_bytes;
- end
-else x:=make_scaled(x*16,internal[design_size]);
+ if x>0 then x:=max_tfm_dimen@+else x:=-max_tfm_dimen;
+ end;
+x:=make_scaled(x*16,internal[design_size]);
dimen_out:=x;
end;
@@ -23166,7 +23243,7 @@ var @!p:pointer; {the current graphical object}
@!cur_fsize:array[font_number] of pointer; {current positions in |font_sizes|}
@!ds,@!scf:scaled; {design size and scale factor for a text node}
@!transformed:boolean; {is the coordinate system being transformed?}
-begin open_output_file;
+begin ldf:=null_font; open_output_file;
non_ps_setting:=selector; selector:=ps_file_only;@/
if (internal[prologues]=two)or(internal[prologues]=three) then begin
@<Print improved initial comment and bounding box for edge structure~|h|@>;
@@ -23792,7 +23869,7 @@ if ldf<>null_font then begin
if internal[mpprocset]>0 then begin
print_nl("%%BeginResource: procset mpost");
if (internal[prologues]>0)and(ldf<>null_font) then
- print("/bd{bind def}bind def/fshow {exch findfont exch scalefont setfont show}bd")
+ print_nl("/bd{bind def}bind def/fshow {exch findfont exch scalefont setfont show}bd")
else
print_nl("/bd{bind def}bind def");
@<Print the procset@>;
@@ -23919,7 +23996,7 @@ so that the inverse relation between them is clear.
The global variable |mem_ident| is a string that is printed right
after the |banner| line when \MP\ is ready to start. For \.{INIMP} this
string says simply `\.{(INIMP)}'; for other versions of \MP\ it says,
-for example, `\.{(preloaded mem=plain 90.4.14)}', showing the year,
+for example, `\.{(preloaded mem=plain 1990.4.14)}', showing the year,
month, and day that the mem file was created. We have |mem_ident=0|
before \MP's tables are loaded.
diff --git a/Build/source/texk/web2c/mpdir/makecpool.c b/Build/source/texk/web2c/mpdir/makecpool.c
index 7d37035b9fd..728e1f86654 100644
--- a/Build/source/texk/web2c/mpdir/makecpool.c
+++ b/Build/source/texk/web2c/mpdir/makecpool.c
@@ -6,58 +6,76 @@
#include <stdlib.h>
int main(int argc, char *argv[]) {
- char *filename, *headername, data[1024];
+ char *filename;
+ char *headername;
FILE *fh;
+ char data[1024];
+ int is_metapost = 0;
+ int is_luatex = 0;
if (argc!=3) {
- puts("Need exactly two arguments: pool_name and header_name");
- exit(1);
+ fprintf(stderr,"%s: need exactly two arguments (pool name and C header name).\n", argv[0]);
+ exit(EXIT_FAILURE);
}
filename = argv[1];
headername = argv[2];
fh = fopen(filename,"r");
+ if (!fh) {
+ fprintf(stderr,"%s: can't open %s for reading.\n", argv[0], filename);
+ exit(EXIT_FAILURE);
+ }
+ if (strstr(filename,"luatex.pool")!=NULL)
+ is_luatex = 1;
+ else if (strstr(filename,"mp.pool")!=NULL)
+ is_metapost = 1;
printf(
- "/* This file is auto-generated by makecpool */\n"
+ "/*\n"
+ " * This file is auto-generated by makecpool. \n"
+ " * %s %s %s\n"
+ " */\n"
"\n"
"#include <stdio.h>\n"
- "#include <strings.h>\n"
+ "#include <string.h>\n"
"#include \"%s\"\n"
"\n"
- "static char *poolfilearr[] = {\n",headername);
+ "static const char *poolfilearr[] = {\n", argv[0], filename, headername, headername);
while (fgets(data,1024,fh)) {
- int len = strlen(data);
- int o = 0; // skip first o characters
int i;
- if (data[len-1]=='\n') { // chomp;
+ int len = strlen(data);
+ int o = 0; /* skip first bytes */
+ if (data[len-1]=='\n') {
data[len-1] = 0;
len--;
}
- if (data[0]=='*') break; // last if /^\*/;
+ if (data[0]=='*') break;
if (data[0]>='0' && data[0]<='9' && data[1]>='0' && data[1]<='9') {
- o=2; // $data =~ s/^\d\d//;
+ o=2;
}
printf(" \"");
for (i=o; i<len; i++) {
if (data[i]=='"' || data[i]=='\\') putchar('\\');
if (data[i]=='?') printf("\" \""); /* suppress trigraphs */
putchar(data[i]);
- } // $data =~ s/(["\\])/\\$1/g;
+ }
printf("\",\n");
}
fclose(fh);
printf(" NULL };\n"
"int loadpoolstrings (integer spare_size) {\n"
+ " const char *s;\n"
" strnumber g=0;\n"
" int i=0,j=0;\n"
- " char *s;\n"
" while ((s = poolfilearr[j++])) {\n"
" int l = strlen (s);\n"
" i += l;\n"
- " if (i>=spare_size) return 0;\n"
- " while (l-- > 0) strpool[poolptr++] = *s++;\n"
- " g = makestring();\n"
- " strref[g]= 127;\n"
- " }\n"
- " return g;\n"
- "}\n");
- return 0;
+ " if (i>=spare_size) return 0;\n");
+ if (is_luatex)
+ printf(" while (l-- > 0) str_pool[pool_ptr++] = *s++;\n"
+ " g = make_string();\n");
+ else
+ printf(" while (l-- > 0) strpool[poolptr++] = *s++;\n"
+ " g = makestring();\n");
+ if (is_metapost)
+ printf(" strref[g]= 127;\n");
+ printf(" }\n" " return g;\n" "}\n");
+ return EXIT_SUCCESS;
}
diff --git a/Build/source/texk/web2c/mpdir/mapfile.c b/Build/source/texk/web2c/mpdir/mapfile.c
index 1893b55bfd7..4887c19ad5e 100644
--- a/Build/source/texk/web2c/mpdir/mapfile.c
+++ b/Build/source/texk/web2c/mpdir/mapfile.c
@@ -53,10 +53,6 @@ mapitem *mitem = NULL;
fm_entry *fm_cur;
static const char nontfm[] = "<nontfm>";
-static fm_entry *loaded_tfm_found;
-static fm_entry *avail_tfm_found;
-static fm_entry *non_tfm_found;
-static fm_entry *not_avail_tfm_found;
#define read_field(r, q, buf) do { \
q = buf; \
@@ -726,152 +722,6 @@ ff_entry *check_ff_exist (fm_entry * fm)
return ff;
}
-/**********************************************************************/
-
-static boolean used_tfm (fm_entry * p)
-{
- fontnumber f;
- strnumber s;
- ff_entry *ff;
-
- /* check if the font file is not a TrueType font */
- /* font replacement makes sense only for included Type1 files */
- if (is_truetype (p) || !is_included (p))
- return false;
-
- /* check if the font file is available */
- ff = check_ff_exist (p);
- if (ff->ff_path == NULL)
- return false;
-
- /* check whether this font has been used */
- if (fontsizes[p->tfm_num]!=0)
- return true;
- assert (p->tfm_name != NULL);
-
- /* check whether we didn't find a loaded font yet,
- * and this font has been loaded */
- if (loaded_tfm_found == NULL && strcmp (p->tfm_name, nontfm)) {
- s = maketexstring (p->tfm_name);
- if ((f = tfmlookup (s, 0)) != getnullfont ()) {
- loaded_tfm_found = p;
- if (mpfontmap[f] == NULL)
- mpfontmap[f] = (fmentryptr) p;
- if (p->tfm_num == getnullfont ())
- p->tfm_num = f;
- assert (p->tfm_num == f);
- /* don't call flushstr() here as it has been called by tfmlookup() */
- } else
- flushstr (s);
- }
-
- /* check whether we didn't find either a loaded or a loadable font yet,
- * and this font is loadable */
- if (avail_tfm_found == NULL && loaded_tfm_found == NULL &&
- strcmp (p->tfm_name, nontfm)) {
- if (p->tfm_avail == TFM_UNCHECKED) {
- if (kpse_find_file (p->tfm_name, kpse_tfm_format, 0) != NULL) {
- avail_tfm_found = p;
- p->tfm_avail = TFM_FOUND;
- } else {
- p->tfm_avail = TFM_NOTFOUND;
- if (not_avail_tfm_found == NULL)
- not_avail_tfm_found = p;
- }
- }
- }
-
- /* check whether the current entry is a <nontfm> entry */
- if (non_tfm_found == NULL && !strcmp (p->tfm_name, nontfm))
- non_tfm_found = p;
-
- return false;
-}
-
-/* lookup_ps_name looks for an entry with a given ps name + slant + extend;
- * return NULL if not found.
- *
- * As there may exist several such entries, we need to select the `right'
- * one. We do so by checking all such entries and return the first one that
- * fulfils the following criteria (in descending priority):
- *
- * - the tfm has been used (some char from this font has been typeset)
- * - the tfm has been loaded (but not used yet)
- * - the tfm can be loaded (but not loaded yet)
- * - the tfm is present in map files, but cannot be loaded. In this case a
- * dummy tfm can be loaded instead, and a warning should be written out
- */
-
-static fm_entry *lookup_ps_name (fm_entry * fm)
-{
- fm_entry *p, *p2;
- struct avl_traverser t, t2;
- int a;
-
- loaded_tfm_found = NULL;
- avail_tfm_found = NULL;
- non_tfm_found = NULL;
- not_avail_tfm_found = NULL;
-
- assert (fm->tfm_name == NULL);
- p = (fm_entry *) avl_t_find (&t, ps_tree, fm);
- if (p == NULL)
- return NULL;
- t2 = t;
- p2 = (fm_entry *) avl_t_prev (&t2);
-
- /* search forward */
- do {
- if (used_tfm (p))
- return p;
- p = (fm_entry *) avl_t_next (&t);
- }
- while (p != NULL && comp_fm_entry_ps (fm, p, NULL) == 0);
-
- /* search backward */
- while (p2 != NULL && comp_fm_entry_ps (fm, p2, NULL) == 0) {
- if (used_tfm (p2))
- return p2;
- p2 = (fm_entry *) avl_t_prev (&t2);
- }
-
- if (loaded_tfm_found != NULL)
- p = loaded_tfm_found;
- else if (avail_tfm_found != NULL) {
- /* TH: do not do this for metapost, there is no embedding anyway */
- /* p = avail_tfm_found;
- * p->tfm_num = readfontinfo (getnullcs (), maketexstring (p->tfm_name),
- * getnullstr (), -1000);
- * p->tfm_avail = TFM_FOUND;
- */
- } else if (non_tfm_found != NULL) {
- p = non_tfm_found;
- p->tfm_num = newdummyfont ();
- p->tfm_avail = TFM_FOUND;
- } else if (not_avail_tfm_found != NULL) {
- p = not_avail_tfm_found;
- pdftex_warn ("`%s' not loadable, use a dummy tfm instead", p->tfm_name);
- p2 = new_fm_entry ();
- p2->flags = p->flags;
- p2->encoding = p->encoding;
- p2->type = p->type;
- p2->slant = p->slant;
- p2->extend = p->extend;
- p2->tfm_name = xstrdup (nontfm);
- p2->ps_name = xstrdup (p->ps_name);
- if (p->ff_name != NULL)
- p2->ff_name = xstrdup (p->ff_name);
- p2->tfm_num = newdummyfont ();
- p2->tfm_avail = TFM_FOUND;
- a = avl_do_entry (p2, FM_DUPIGNORE);
- assert (a == 0);
- p = p2;
- } else
- return NULL;
- assert (p->tfm_num != getnullfont ());
- return p;
-}
-
/**********************************************************************/
/*
diff --git a/Build/source/texk/web2c/mpdir/mplib.h b/Build/source/texk/web2c/mpdir/mplib.h
index 232956dbff7..bc015275e06 100644
--- a/Build/source/texk/web2c/mpdir/mplib.h
+++ b/Build/source/texk/web2c/mpdir/mplib.h
@@ -24,7 +24,7 @@ $Id$
# define MPOSTLIB
/* WEB2C macros and prototypes */
-# if !defined(MPOSTCOERCE)
+# if !defined(MPCOERCE)
# define EXTERN extern
# include "mpd.h"
# endif
@@ -52,27 +52,6 @@ typedef struct {
integer tounicode; /* object number of associated ToUnicode entry */
} enc_entry;
-struct _subfont_entry;
-typedef struct _subfont_entry subfont_entry;
-
-struct _subfont_entry {
- char *infix; /* infix for this subfont, eg "01" */
- long charcodes[256]; /* the mapping for this subfont as read from sfd */
- subfont_entry *next;
-};
-
-typedef struct {
- char *name; /* sfd name, eg "Unicode" */
- subfont_entry *subfont; /* linked list of subfonts */
-} sfd_entry;
-
-typedef struct {
- char *name; /* glyph name */
- long code; /* -1 = undefined; -2 = multiple codes, stored
- as string in unicode_seq; otherwise unicode value */
- char *unicode_seq; /* multiple unicode sequence */
-} glyph_unicode_entry;
-
typedef struct {
char *tfm_name; /* TFM file name */
char *ps_name; /* PostScript name */
@@ -93,7 +72,7 @@ typedef struct {
short tfm_avail; /* flags whether a tfm is available */
short pid; /* Pid for truetype fonts */
short eid; /* Eid for truetype fonts */
- subfont_entry *subfont; /* subfont mapping */
+ void *subfont; /* subfont mapping, not used */
} fm_entry;
typedef struct {
@@ -101,147 +80,60 @@ typedef struct {
char *ff_path; /* full path to font file */
} ff_entry;
-typedef short shalfword;
-typedef struct {
- integer charcode, cwidth, cheight, xoff, yoff, xescape, rastersize;
- halfword *raster;
-} chardesc;
+/* variable declarations */
-/* pdftexlib variable declarations */
extern boolean fontfile_found;
-extern boolean is_otf_font;
-extern boolean true_dimen;
-extern boolean write_ttf_glyph_names;
extern char **t1_glyph_names, *t1_builtin_glyph_names[];
extern char *cur_file_name;
extern const char notdef[];
extern integer t1_length1, t1_length2, t1_length3;
-extern integer ttf_length;
extern key_entry font_keys[];
extern strnumber last_tex_string;
extern size_t last_ptr_index;
extern char fontname_buf[];
-/* pdftexlib function prototypes */
-
-/* epdf.c */
-extern integer get_fontfile_num (int);
-extern integer get_fontname_num (int);
-extern void epdf_free (void);
-extern int is_type1 (fm_entry *);
+/* function prototypes */
/* mapfile.c */
-extern char *mk_basename (char *);
-extern char *mk_exname (char *, int);
-extern fm_entry *lookup_fontmap (char *);
-extern boolean hasfmentry (fontnumber);
-extern fontnumber tfmoffm (fmentryptr);
-extern void checkextfm (strnumber, integer);
+extern int avl_do_entry (fm_entry *, int);
+extern ff_entry *check_ff_exist (fm_entry *);
+extern void delete_fm_entry (fm_entry *);
extern void fm_free (void);
extern void fm_read_info (void);
-extern ff_entry *check_ff_exist (fm_entry *);
-extern void pdfmapfile (integer);
-extern void pdfmapline (integer);
-extern void pdfinitmapfile (string map_name);
+extern boolean hasfmentry (fontnumber);
+extern fm_entry *lookup_fontmap (char *);
+extern void mpmapfile (integer);
+extern void mpmapline (integer);
+extern void mpinitmapfile (int);
extern fm_entry *new_fm_entry (void);
-extern void delete_fm_entry (fm_entry *);
-extern int avl_do_entry (fm_entry *, int);
-
-/* papersiz.c */
-extern integer myatodim (char **);
-extern integer myatol (char **);
-
-/* pkin.c */
-extern int readchar (boolean, chardesc *);
-
-/* subfont.c */
-extern void sfd_free (void);
-extern boolean handle_subfont_fm (fm_entry *, int);
-
-/* tounicode.c */
-extern void glyph_unicode_free (void);
-extern void deftounicode (strnumber, strnumber);
-extern integer write_tounicode (char **, char *);
+extern fontnumber tfmoffm (fmentryptr);
/* utils.c */
-extern boolean str_eq_cstr (strnumber, char *);
-extern char *makecstring (integer);
-extern int xfflush (FILE *);
-extern int xgetc (FILE *);
-extern int xputc (int, FILE *);
+extern char *convertStringToPDFString (const char *in, int len);
+extern void escapehex (poolpointer in);
+extern void escapename (poolpointer in);
+extern void escapestring (poolpointer in);
extern scaled extxnoverd (scaled, scaled, scaled);
-extern size_t xfwrite (void *, size_t size, size_t nmemb, FILE *);
-extern strnumber getresnameprefix (void);
-extern strnumber maketexstring (const char *);
-extern integer fb_offset (void);
-extern void fb_flush (void);
-extern void fb_putchar (eightbits b);
-extern void fb_seek (integer);
-extern void libpdffinish (void);
-extern char *makecfilename (strnumber s);
+extern void initversionstring (char **versions);
extern void make_subset_tag (fm_entry *, char **, int);
+extern char *makecfilename (strnumber s);
+extern char *makecstring (integer);
+extern strnumber maketexstring (const char *);
+extern void mp_printf (const char *, ...);
extern void pdf_printf (const char *, ...);
extern void pdf_puts (const char *);
extern void pdftex_fail (const char *, ...);
extern void pdftex_warn (const char *, ...);
extern void setjobid (int, int, int, int);
-extern void mp_printf (const char *, ...);
-extern void writestreamlength (integer, integer);
-extern char *convertStringToPDFString (const char *in, int len);
-extern void printID (strnumber);
-extern void printcreationdate ();
-extern void printmoddate ();
-extern void escapename (poolpointer in);
-extern void escapestring (poolpointer in);
-extern void escapehex (poolpointer in);
-extern void unescapehex (poolpointer in);
-extern void getcreationdate ();
-extern void getfilemoddate (strnumber s);
-extern void getfilesize (strnumber s);
-extern void getmd5sum (strnumber s, boolean file);
-extern void getfiledump (strnumber s, int offset, int length);
-extern void matchstrings (strnumber s, strnumber t, int subcount,
- boolean icase);
-extern void getmatch (int i);
-extern void makepdftexbanner (void);
-extern void initstarttime ();
-extern void removepdffile (void);
-extern void garbagewarning (void);
extern void stripspaces (char *p);
-extern void initversionstring (char **versions);
-extern int newcolorstack (integer s, integer literal_mode, boolean pagestart);
-extern int colorstackused ();
-extern integer colorstackset (int colstack_no, integer s);
-extern integer colorstackpush (int colstack_no, integer s);
-extern integer colorstackpop (int colstack_no);
-extern integer colorstackcurrent (int colstack_no);
-extern integer colorstackskippagestart (int colstack_no);
-extern void checkpdfsave (int cur_h, int cur_v);
-extern void checkpdfrestore (int cur_h, int cur_v);
-extern void pdfshipoutbegin (boolean shipping_page);
-extern void pdfshipoutend (boolean shipping_page);
-extern void pdfsetmatrix (poolpointer in, scaled cur_h, scaled cur_v);
-extern void matrixtransformpoint (scaled x, scaled y);
-extern void matrixtransformrect (scaled llx, scaled lly, scaled urx,
- scaled ury);
-extern boolean matrixused ();
-extern void matrixrecalculate (scaled urx);
-extern scaled getllx ();
-extern scaled getlly ();
-extern scaled geturx ();
-extern scaled getury ();
-
-/* vfpacket.c */
-extern eightbits packetbyte (void);
-extern integer newvfpacket (fontnumber);
-extern void poppacketstate (void);
-extern void pushpacketstate (void);
-extern void startpacket (fontnumber, integer);
-extern void storepacket (integer, integer, integer);
-extern void vf_free (void);
+extern char *stripzeros (char *a);
+extern void unescapehex (poolpointer in);
+extern int xfflush (FILE *);
+extern size_t xfwrite (void *, size_t size, size_t nmemb, FILE *);
+extern int xgetc (FILE *);
+extern int xputc (int, FILE *);
/* writeenc.c */
-extern boolean indexed_enc (fm_entry *);
extern enc_entry *add_enc (char *);
extern void enc_free (void);
extern void read_enc (enc_entry *);
@@ -249,50 +141,26 @@ extern void write_enc (char **, enc_entry *, integer);
/* writefont.c */
extern boolean dopsfont (fontnumber);
-
-/* writeimg.c */
-extern boolean checkimageb (integer);
-extern boolean checkimagec (integer);
-extern boolean checkimagei (integer);
-extern boolean ispdfimage (integer);
-extern integer epdforigx (integer);
-extern integer epdforigy (integer);
-extern integer imageheight (integer);
-extern integer imagepages (integer);
-extern integer imagewidth (integer);
-extern integer imagexres (integer);
-extern integer imageyres (integer);
-extern integer readimage (strnumber, integer, strnumber, integer, integer,
- integer, integer);
-extern void deleteimage (integer);
-extern void img_free (void);
-extern void updateimageprocset (integer);
-extern void writeimage (integer);
-extern integer imagecolordepth (integer img);
-
-/* writejbig2.c */
-extern void flushjbig2page0objects ();
+extern strnumber fmencodingname (fontnumber);
+extern integer fmfontextend (fontnumber);
+extern strnumber fmfontname (fontnumber);
+extern integer fmfontslant (fontnumber);
+extern strnumber fmfontsubsetname (fontnumber);
+extern boolean fontisincluded (fontnumber);
+extern boolean fontissubsetted (fontnumber);
+extern boolean fontisreencoded (fontnumber);
+extern void mpfontencodings (int, int);
+extern void mploadencodings (int);
/* writet1.c */
-extern boolean t1_subset (char *, char *, unsigned char *);
extern void load_enc (char *, char **, char **);
-extern void writet1 (int, fm_entry *);
extern void t1_free (void);
+extern boolean t1_subset (char *, char *, unsigned char *);
+extern int t1_updatefm (int, fm_entry *);
+extern void writet1 (int, fm_entry *);
#define bitfile psfile
-/* writet3.c */
-extern void writet3 (int, fontnumber);
-extern scaled getpkcharwidth (fontnumber, scaled);
-
-/* writettf.c */
-extern void writettf (void);
-extern void writeotf (void);
-extern void ttf_free (void);
-
-/* writezip.c */
-extern void writezip (boolean);
-
/* avlstuff.c */
extern void avlputobj (integer, integer);
extern integer avlfindobj (integer, integer, integer);
@@ -301,4 +169,8 @@ extern integer avlfindobj (integer, integer, integer);
extern angle bezierslope(integer,integer,integer,integer,integer,integer,integer,integer,int);
+/* loadpool.c */
+
+extern int loadpoolstrings (integer);
+
#endif /* MPOSTLIB */
diff --git a/Build/source/texk/web2c/mpdir/utils.c b/Build/source/texk/web2c/mpdir/utils.c
index 16de3f5a8d3..00e51cc5edc 100644
--- a/Build/source/texk/web2c/mpdir/utils.c
+++ b/Build/source/texk/web2c/mpdir/utils.c
@@ -52,7 +52,6 @@ static const char perforce_id[] =
char *cur_file_name = NULL;
strnumber last_tex_string;
static char print_buf[PRINTF_BUF_SIZE];
-static char *jobname_cstr = NULL;
static char *job_id_string = NULL;
extern string ptexbanner; /* from web2c/lib/texmfmp.c */
extern string versionstring; /* from web2c/lib/version.c */
@@ -105,14 +104,6 @@ void mp_printf (const char *fmt, ...)
selector = saved_selector; /* ps_file_only, probably */
}
-/* Helper for pdftex_fail. */
-static void safe_print (const char *str)
-{
- const char *c;
- for (c = str; *c; ++c)
- print (*c);
-}
-
/* pdftex_fail may be called when a buffer overflow has happened/is
happening, therefore may not call mktexstring. However, with the
current implementation it appears that error messages are misleading,
@@ -480,27 +471,6 @@ void unescapehex (poolpointer in)
}
-/* Converts any string given in in in an allowed PDF string which is
- * hexadecimal encoded;
- * sizeof(out) should be at least lin*2+1.
- */
-static void convertStringToHexString (const char *in, char *out, int lin)
-{
- int i, j, k;
- char buf[3];
- j = 0;
- for (i = 0; i < lin; i++) {
- k = snprintf (buf, sizeof (buf),
- "%02X", (unsigned int) (unsigned char) in[i]);
- check_nprintf (k, sizeof (buf));
- out[j++] = buf[0];
- out[j++] = buf[1];
- }
- out[j] = '\0';
-}
-
-
-
/* makecfilename
input/ouput same as makecstring:
input: string number
@@ -650,7 +620,7 @@ static void fnstr_append (const char *s)
/* this is not really a true crc32, but it should be just enough to keep
subsets prefixes somewhat disjunct */
unsigned long crc32 (int oldcrc, const Byte *buf, int len) {
- unsigned long ret;
+ unsigned long ret = 0;
int i;
if (oldcrc==0)
ret = (23<<24)+(45<<16)+(67<<8)+89;
@@ -667,7 +637,7 @@ void make_subset_tag (fm_entry * fm_cur, char **glyph_names, int tex_font)
int i;
size_t l ;
if (job_id_string ==NULL)
- exit;
+ exit(1);
l = strlen (job_id_string) + 1;
alloc_array (char, l, SMALL_ARRAY_SIZE);
diff --git a/Build/source/texk/web2c/mpdir/writeenc.c b/Build/source/texk/web2c/mpdir/writeenc.c
index 30673cd6aa3..ac4dc5cba7b 100644
--- a/Build/source/texk/web2c/mpdir/writeenc.c
+++ b/Build/source/texk/web2c/mpdir/writeenc.c
@@ -42,7 +42,6 @@ void read_enc (enc_entry * e)
*/
void write_enc (char **glyph_names, enc_entry * e, integer eobjnum)
{
- boolean is_notdef;
int i;
int s;
int foffset;
diff --git a/Build/source/texk/web2c/mpdir/writefont.c b/Build/source/texk/web2c/mpdir/writefont.c
index 899b42b54a2..528e1577bd1 100644
--- a/Build/source/texk/web2c/mpdir/writefont.c
+++ b/Build/source/texk/web2c/mpdir/writefont.c
@@ -29,7 +29,7 @@ boolean fontfile_found;
boolean is_otf_font;
char fontname_buf[FONTNAME_BUF_SIZE];
-boolean fontisreencoded (int f) {
+boolean fontisreencoded (fontnumber f) {
fm_entry *fm;
if (fontsizes[f]!=0 && hasfmentry (f)) {
fm = (fm_entry *) mpfontmap[f];
@@ -41,7 +41,7 @@ boolean fontisreencoded (int f) {
return 0;
}
-boolean fontisincluded (int f) {
+boolean fontisincluded (fontnumber f) {
fm_entry *fm;
if (fontsizes[f]!=0 && hasfmentry (f)) {
fm = (fm_entry *) mpfontmap[f];
@@ -53,7 +53,7 @@ boolean fontisincluded (int f) {
return 0;
}
-boolean fontissubsetted (int f) {
+boolean fontissubsetted (fontnumber f) {
fm_entry *fm;
if (fontsizes[f]!=0 && hasfmentry (f)) {
fm = (fm_entry *) mpfontmap[f];
@@ -66,7 +66,7 @@ boolean fontissubsetted (int f) {
}
-strnumber fmencodingname (int f) {
+strnumber fmencodingname (fontnumber f) {
enc_entry *e;
fm_entry *fm;
if (hasfmentry (f)) {
@@ -86,7 +86,7 @@ strnumber fmencodingname (int f) {
return 0;
}
-strnumber fmfontname (int f) {
+strnumber fmfontname (fontnumber f) {
fm_entry *fm;
if (hasfmentry (f)) {
fm = (fm_entry *) mpfontmap[f];
@@ -106,7 +106,7 @@ strnumber fmfontname (int f) {
return 0;
}
-strnumber fmfontsubsetname (int f) {
+strnumber fmfontsubsetname (fontnumber f) {
fm_entry *fm;
char *s;
if (hasfmentry (f)) {
@@ -127,7 +127,7 @@ strnumber fmfontsubsetname (int f) {
-integer fmfontslant (int f) {
+integer fmfontslant (fontnumber f) {
fm_entry *fm;
if (hasfmentry (f)) {
fm = (fm_entry *) mpfontmap[f];
@@ -138,7 +138,7 @@ integer fmfontslant (int f) {
return 0;
}
-integer fmfontextend (int f) {
+integer fmfontextend (fontnumber f) {
fm_entry *fm;
if (hasfmentry (f)) {
fm = (fm_entry *) mpfontmap[f];
@@ -172,7 +172,7 @@ void mploadencodings (int lastfnum) {
void mpfontencodings (int lastfnum, int encodings_only) {
int nullfont;
- int f,ff;
+ int f;
enc_entry *e;
fm_entry *fm;
nullfont = getnullfont();
@@ -195,7 +195,6 @@ void mpfontencodings (int lastfnum, int encodings_only) {
boolean dopsfont (fontnumber f)
{
- int i;
fm_entry *fm_cur;
if (mpfontmap[f] == NULL)
pdftex_fail ("pdffontmap not initialized for font %s",
diff --git a/Build/source/texk/web2c/mpdir/writet1.c b/Build/source/texk/web2c/mpdir/writet1.c
index bbfd398aa3b..3823a7650da 100644
--- a/Build/source/texk/web2c/mpdir/writet1.c
+++ b/Build/source/texk/web2c/mpdir/writet1.c
@@ -60,10 +60,6 @@ extern Boolean shiftlowchars;
# define fixedcontent true
static char *dvips_extra_charset;
-static char *cur_enc_name;
-static unsigned char *grid;
-static char *ext_glyph_names[256];
-static char print_buf[PRINTF_BUF_SIZE];
static int hexline_length;
const char notdef[] = ".notdef";
/* static size_t last_ptr_index; */
@@ -757,7 +753,7 @@ key_entry font_keys[FONT_KEYS_NUM] = {
static void t1_scan_keys (int tex_font,fm_entry *fm_cur)
{
int i, k;
- char *p, *q, *r;
+ char *p, *r;
key_entry *key;
if (fm_extend (fm_cur) != 0 || fm_slant (fm_cur) != 0) {
if (t1_prefix ("/FontMatrix")) {
@@ -1691,7 +1687,7 @@ int t1_updatefm (int f, fm_entry *fm)
}
t1_scan_only (f, fm);
s = xstrdup(fontname_buf);
- for (p=s; *p != ' ' && *p != 0; *p++);
+ for (p=s;*p != ' ' && *p != 0; p++);
*p=0;
fm->ps_name = s;
t1_close_font_file ("");
diff --git a/Build/source/texk/web2c/mpware/mpto.c b/Build/source/texk/web2c/mpware/mpto.c
index 593dc1a43cd..04ee33a6271 100644
--- a/Build/source/texk/web2c/mpware/mpto.c
+++ b/Build/source/texk/web2c/mpware/mpto.c
@@ -50,7 +50,7 @@ char *tex_pretex = "\\mpxshipout%% line %d %s\n";
char *tex_posttex = "\n\\stopmpxshipout\n";
char *tex_preverb1 = ""; /* if very first instance */
char *tex_preverb = "%% line %d %s\n"; /* all other instances */
-char *tex_postverb = "%\n";
+char *tex_postverb = "\n";
/* According to CSTR #54 the ".lf" directive should be ".lf %d %s",
* not ".lf line %d %s" as used in the original code. This affects
@@ -297,6 +297,7 @@ void
copytex(void)
{
char *s; /* where a string to print stops */
+ char *t; /* for finding start of last line */
char c;
char *res = NULL;
do {
@@ -333,12 +334,18 @@ copytex(void)
/* whitespace at the end */
for (s = res + strlen(res) - 1;
s >= res && (*s == ' ' || *s == '\t' || *s == '\r' || *s == '\n'); s--);
+ t = s;
*(++s) = '\0';
/* whitespace at the start */
for (s = res;
s < (res + strlen(res)) && (*s == ' ' || *s == '\t' || *s == '\r'
|| *s == '\n'); s++);
- printf("%s%%",s);
+ for (; *t != '\n' && t > s; t--);
+ printf("%s", s);
+ /* put no '%' at end if it's only 1 line total, starting with '%';
+ * this covers the special case "%&format" in a single line. */
+ if (t != s || *t != '%')
+ printf("%%");
free(res);
}
@@ -397,7 +404,7 @@ main(int argc, char **argv)
exit(0);
} else if (argc > 1 && (strcmp(argv[1], "--version") == 0
|| strcmp(argv[1], "-version") == 0)) {
- printf("mpto 1.002\n\
+ printf("mpto 1.003\n\
This program is in the public domain.\n\
Primary author of mpto: John Hobby.\n\
Current maintainer: Taco Hoekwater.\n");