summaryrefslogtreecommitdiff
path: root/Build
diff options
context:
space:
mode:
authorTaco Hoekwater <taco@elvenkind.com>2009-04-22 14:59:30 +0000
committerTaco Hoekwater <taco@elvenkind.com>2009-04-22 14:59:30 +0000
commit6619094417b7606acce5c62de157d426351d5775 (patch)
treeec43633a720cfc6a3a397e40761add44d7d20878 /Build
parent7e47c9020771d03e870046d5e7131c3dc5b03e61 (diff)
Import mplib version 1.200
git-svn-id: svn://tug.org/texlive/trunk@12790 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build')
-rw-r--r--Build/source/texk/web2c/mplibdir/ChangeLog3
-rw-r--r--Build/source/texk/web2c/mplibdir/avl.h1
-rw-r--r--Build/source/texk/web2c/mplibdir/lmplib.c17
-rw-r--r--Build/source/texk/web2c/mplibdir/memio.w2
-rw-r--r--Build/source/texk/web2c/mplibdir/mp.w591
-rw-r--r--Build/source/texk/web2c/mplibdir/mpost.w202
-rw-r--r--Build/source/texk/web2c/mplibdir/mpxout.w102
-rw-r--r--Build/source/texk/web2c/mplibdir/psout.w322
-rw-r--r--Build/source/texk/web2c/mplibdir/svgout.w10
9 files changed, 973 insertions, 277 deletions
diff --git a/Build/source/texk/web2c/mplibdir/ChangeLog b/Build/source/texk/web2c/mplibdir/ChangeLog
new file mode 100644
index 00000000000..9c9c5aa937e
--- /dev/null
+++ b/Build/source/texk/web2c/mplibdir/ChangeLog
@@ -0,0 +1,3 @@
+2009-04-22 Taco Hoekwater <taco@elvenkind.com>
+
+ * Import of MPlib version 1.200
diff --git a/Build/source/texk/web2c/mplibdir/avl.h b/Build/source/texk/web2c/mplibdir/avl.h
index a78d50b91cf..d5d2ada72d3 100644
--- a/Build/source/texk/web2c/mplibdir/avl.h
+++ b/Build/source/texk/web2c/mplibdir/avl.h
@@ -16,7 +16,6 @@
#define avl_tree mp_avl_tree
#define avl_entry mp_avl_entry
#define avl_find mp_avl_find
-#define avl_probe mp_avl_probe
#define avl_create mp_avl_create
#define avl_destroy mp_avl_destroy
diff --git a/Build/source/texk/web2c/mplibdir/lmplib.c b/Build/source/texk/web2c/mplibdir/lmplib.c
index 8e0823ece06..b5e6959c3ea 100644
--- a/Build/source/texk/web2c/mplibdir/lmplib.c
+++ b/Build/source/texk/web2c/mplibdir/lmplib.c
@@ -35,6 +35,7 @@
#include "mplib.h"
#include "mplibps.h"
+#include "mplibsvg.h"
/*@unused@*/ static const char _svn_version[] =
"$Id: lmplib.c 1364 2008-07-04 16:09:46Z taco $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/lua/lmplib.c $";
@@ -585,6 +586,21 @@ static int mplib_fig_postscript(lua_State * L)
return 1;
}
+static int mplib_fig_svg(lua_State * L)
+{
+ mp_run_data *res;
+ struct mp_edge_object **hh = is_fig(L, 1);
+ int prologues = (int)luaL_optnumber(L, 2, (lua_Number)-1);
+ if (mp_svg_ship_out(*hh, prologues)
+ && (res = mp_rundata((*hh)->parent))
+ && (res->ps_out.size != 0)) {
+ lua_pushstring(L, res->ps_out.data);
+ } else {
+ lua_pushnil(L);
+ }
+ return 1;
+}
+
static int mplib_fig_filename(lua_State * L)
{
struct mp_edge_object **hh = is_fig(L, 1);
@@ -1176,6 +1192,7 @@ static const struct luaL_reg mplib_fig_meta[] = {
{"copy_objects", mplib_fig_copy_body},
{"filename", mplib_fig_filename},
{"postscript", mplib_fig_postscript},
+ {"svg", mplib_fig_svg},
{"boundingbox", mplib_fig_bb},
{"width", mplib_fig_width},
{"height", mplib_fig_height},
diff --git a/Build/source/texk/web2c/mplibdir/memio.w b/Build/source/texk/web2c/mplibdir/memio.w
index d2393d0fb96..f5492f713b5 100644
--- a/Build/source/texk/web2c/mplibdir/memio.w
+++ b/Build/source/texk/web2c/mplibdir/memio.w
@@ -352,6 +352,7 @@ dump_int(mp->max_internal);
dump_int(mp->int_ptr);
for (k=1;k<= mp->int_ptr;k++ ) {
dump_int(mp->internal[k]);
+ dump_int(mp->int_type[k]);
dump_string(mp->int_name[k]);
}
dump_int(mp->start_sym);
@@ -366,6 +367,7 @@ if (x>mp->max_internal) mp_grow_internals(mp,x);
undump_int(mp->int_ptr);
for (k=1;k<= mp->int_ptr;k++) {
undump_int(mp->internal[k]);
+ undump_int(mp->int_type[k]);
undump_string(mp->int_name[k]);
}
undump(0,frozen_inaccessible,mp->start_sym);
diff --git a/Build/source/texk/web2c/mplibdir/mp.w b/Build/source/texk/web2c/mplibdir/mp.w
index 1303cf6f9e4..f49d5a451f9 100644
--- a/Build/source/texk/web2c/mplibdir/mp.w
+++ b/Build/source/texk/web2c/mplibdir/mp.w
@@ -1,4 +1,4 @@
-% $Id: mp.w 873 2009-03-19 07:44:11Z taco $
+% $Id: mp.w 976 2009-04-22 07:55:33Z taco $
%
% Copyright 2008 Taco Hoekwater.
%
@@ -89,13 +89,13 @@ undergoes any modifications, so that it will be clear which version of
@^extensions to \MP@>
@^system dependencies@>
-@d default_banner "This is MetaPost, Version 1.110" /* printed when \MP\ starts */
+@d default_banner "This is MetaPost, Version 1.200" /* printed when \MP\ starts */
@d true 1
@d false 0
@(mpmp.h@>=
-#define metapost_version "1.110"
-#define metapost_magic (('M'*256) + 'P')*65536 + 1110
+#define metapost_version "1.200"
+#define metapost_magic (('M'*256) + 'P')*65536 + 1200
#define metapost_old_magic (('M'*256) + 'P')*65536 + 1080
@ The external library header for \MP\ is |mplib.h|. It contains a
@@ -282,6 +282,7 @@ MP mp_initialize (MP_options *opt) {
} else {
mp->history=mp_spotless;
}
+ @<Fix up |mp->internal[mp_job_name]|@>;
return mp;
}
@@ -663,6 +664,9 @@ int file_line_error_style; /* configuration parameter */
mp->file_line_error_style = (opt->file_line_error_style>0 ? true : false);
mp->long_name = NULL;
+@ @<Dealloc variables@>=
+mp_xfree(mp->long_name);
+
@ \MP's file-opening procedures return |false| if no file identified by
|name_of_file| could be opened.
@@ -1482,6 +1486,21 @@ static boolean mp_str_eq_buf (MP mp,str_number s, integer k) {
return true;
}
+@ This routine compares a pool string with a sequence of characters
+of equal length.
+
+@c
+static boolean mp_str_eq_cstr (MP mp,str_number s, char *k) {
+ /* test equality of strings */
+ pool_pointer j; /* running index */
+ j=mp->str_start[s];
+ while ( j<str_stop(s) ) {
+ if ( mp->str_pool[j++]!=*k++ )
+ return false;
+ }
+ return true;
+}
+
@ Here is a similar routine, but it compares two strings in the string pool,
and it does not assume that they have the same length. If the first string
is lexicographically greater than, less than, or equal to the second,
@@ -3996,10 +4015,12 @@ void mp_do_snprintf (char *str, int size, const char *format, ...) {
if (*fmt=='%') {
fw=0;
pad=0;
+ RESTART:
fmt++;
switch(*fmt) {
case '0':
pad=1;
+ goto RESTART;
break;
case '1':
case '2':
@@ -4010,9 +4031,10 @@ void mp_do_snprintf (char *str, int size, const char *format, ...) {
case '7':
case '8':
case '9':
- assert(fw==0);
- fw = *fmt-'0';
- break;
+ assert(fw==0);
+ fw = *fmt-'0';
+ goto RESTART;
+ break;
case 's':
{
char *s = va_arg(ap, char *);
@@ -4022,10 +4044,18 @@ void mp_do_snprintf (char *str, int size, const char *format, ...) {
}
}
break;
+ case 'c':
+ {
+ int s = va_arg(ap, int);
+ *res = s;
+ if (size-->0) res++;
+ }
+ break;
case 'i':
case 'd':
{
- char *s = mp_itoa(va_arg(ap, int));
+ char *sstart, *s = mp_itoa(va_arg(ap, int));
+ sstart = s;
if (fw) {
int ffw = fw-strlen(s);
while (ffw-->0) {
@@ -4038,12 +4068,14 @@ void mp_do_snprintf (char *str, int size, const char *format, ...) {
*res = *s++;
if (size-->0) res++;
}
+ mp_xfree(sstart);
}
}
break;
case 'u':
{
- char *s = mp_utoa(va_arg(ap, unsigned));
+ char *sstart, *s = mp_utoa(va_arg(ap, unsigned));
+ sstart = s;
if (fw) {
int ffw = fw-strlen(s);
while (ffw-->0) {
@@ -4056,6 +4088,7 @@ void mp_do_snprintf (char *str, int size, const char *format, ...) {
*res = *s++;
if (size-->0) res++;
}
+ mp_xfree(sstart);
}
}
break;
@@ -4786,7 +4819,8 @@ and |string_type| in that order.
@<Types...@>=
enum mp_variable_type {
-mp_vacuous=1, /* no expression was present */
+mp_internal_type=0, /* an internal that has not been frozen yet */
+mp_vacuous, /* no expression was present */
mp_boolean_type, /* \&{boolean} with a known value */
mp_unknown_boolean,
mp_string_type, /* \&{string} with a known value */
@@ -4818,6 +4852,7 @@ static void mp_print_type (MP mp,quarterword t) ;
@ @<Basic printing procedures@>=
void mp_print_type (MP mp,quarterword t) {
switch (t) {
+ case mp_internal_type:mp_print(mp, "new internal"); break;
case mp_vacuous:mp_print(mp, "mp_vacuous"); break;
case mp_boolean_type:mp_print(mp, "boolean"); break;
case mp_unknown_boolean:mp_print(mp, "unknown boolean"); break;
@@ -4892,7 +4927,6 @@ values they test for.
@d false_code 31 /* operation code for \.{false} */
@d null_picture_code 32 /* operation code for \.{nullpicture} */
@d null_pen_code 33 /* operation code for \.{nullpen} */
-@d job_name_op 34 /* operation code for \.{jobname} */
@d read_string_op 35 /* operation code for \.{readstring} */
@d pen_circle 36 /* operation code for \.{pencircle} */
@d normal_deviate 37 /* operation code for \.{normaldeviate} */
@@ -4990,6 +5024,7 @@ values they test for.
@d arc_time_of 128 /* operation code for \.{arctime} */
@d mp_version 129 /* operation code for \.{mpversion} */
@d envelope_of 130 /* operation code for \.{envelope} */
+@d glyph_infont 131 /* operation code for \.{glyph} */
@c static void mp_print_op (MP mp,quarterword c) {
if (c<=mp_numeric_type ) {
@@ -5000,7 +5035,6 @@ values they test for.
case false_code:mp_print(mp, "false"); break;
case null_picture_code:mp_print(mp, "nullpicture"); break;
case null_pen_code:mp_print(mp, "nullpen"); break;
- case job_name_op:mp_print(mp, "jobname"); break;
case read_string_op:mp_print(mp, "readstring"); break;
case pen_circle:mp_print(mp, "pencircle"); break;
case normal_deviate:mp_print(mp, "normaldeviate"); break;
@@ -5096,6 +5130,7 @@ values they test for.
case arc_time_of:mp_print(mp, "arctime"); break;
case mp_version:mp_print(mp, "mpversion"); break;
case envelope_of:mp_print(mp, "envelope"); break;
+ case glyph_infont:mp_print(mp, "glyph"); break;
default: mp_print(mp, ".."); break;
}
}
@@ -5108,6 +5143,8 @@ fuss with. Every such parameter has an identifying code number, defined here.
enum mp_given_internal {
mp_output_template=1, /* a string set up by \&{outputtemplate} */
mp_output_format, /* the output format set up by \&{outputformat} */
+ mp_job_name, /* the perceived jobname, as set up from the options stucture,
+ the name of the input file, or by \&{jobname} */
mp_tracing_titles, /* show titles online when they appear */
mp_tracing_equations, /* show each variable when it becomes known */
mp_tracing_capsules, /* show capsules too */
@@ -5124,6 +5161,8 @@ enum mp_given_internal {
mp_month, /* the current month (e.g., 3 $\equiv$ March) */
mp_day, /* the current day of the month */
mp_time, /* the number of minutes past midnight when this job started */
+ mp_hour, /* the number of hours past midnight when this job started */
+ mp_minute, /* the number of minutes in that hour when this job started */
mp_char_code, /* the number of the next character to be output */
mp_char_ext, /* the extension code of the next character to be output */
mp_char_wd, /* the width of the next character to be output */
@@ -5153,6 +5192,7 @@ enum mp_given_internal {
@<Glob...@>=
scaled *internal; /* the values of internal quantities */
+int *int_type; /* their types */
char **int_name; /* their names */
int int_ptr; /* the maximum internal quantity defined so far */
int max_internal; /* current maximum number of internal quantities */
@@ -5166,6 +5206,16 @@ mp->internal = xmalloc ((mp->max_internal+1), sizeof(scaled));
memset(mp->internal,0,(mp->max_internal+1)* sizeof(scaled));
mp->int_name = xmalloc ((mp->max_internal+1), sizeof(char *));
memset(mp->int_name,0,(mp->max_internal+1) * sizeof(char *));
+mp->int_type = xmalloc ((mp->max_internal+1), sizeof(int));
+memset(mp->int_type,0,(mp->max_internal+1) * sizeof(int));
+{
+ int i;
+ for (i=1;i<=max_given_internal;i++)
+ mp->int_type[i]=mp_known;
+}
+mp->int_type[mp_output_format]=mp_string_type;
+mp->int_type[mp_output_template]=mp_string_type;
+mp->int_type[mp_job_name]=mp_string_type;
mp->troff_mode=(opt->troff_mode>0 ? true : false);
@ @<Exported function ...@>=
@@ -5215,6 +5265,10 @@ mp_primitive(mp, "day",internal_quantity,mp_day);
@:mp_day_}{\&{day} primitive@>
mp_primitive(mp, "time",internal_quantity,mp_time);
@:time_}{\&{time} primitive@>
+mp_primitive(mp, "hour",internal_quantity,mp_hour);
+@:hour_}{\&{hour} primitive@>
+mp_primitive(mp, "minute",internal_quantity,mp_minute);
+@:minute_}{\&{minute} primitive@>
mp_primitive(mp, "charcode",internal_quantity,mp_char_code);
@:mp_char_code_}{\&{charcode} primitive@>
mp_primitive(mp, "charext",internal_quantity,mp_char_ext);
@@ -5261,6 +5315,8 @@ mp_primitive(mp, "outputtemplate",internal_quantity,mp_output_template);
@:mp_output_template_}{\&{outputtemplate} primitive@>
mp_primitive(mp, "outputformat",internal_quantity,mp_output_format);
@:mp_output_format_}{\&{outputformat} primitive@>
+mp_primitive(mp, "jobname",internal_quantity,mp_job_name);
+@:mp_job_name_}{\&{jobname} primitive@>
@ Colors can be specified in four color models. In the special
case of |no_model|, MetaPost does not output any color operator to
@@ -5310,6 +5366,8 @@ mp->int_name[mp_year]=xstrdup("year");
mp->int_name[mp_month]=xstrdup("month");
mp->int_name[mp_day]=xstrdup("day");
mp->int_name[mp_time]=xstrdup("time");
+mp->int_name[mp_hour]=xstrdup("hour");
+mp->int_name[mp_minute]=xstrdup("minute");
mp->int_name[mp_char_code]=xstrdup("charcode");
mp->int_name[mp_char_ext]=xstrdup("charext");
mp->int_name[mp_char_wd]=xstrdup("charwd");
@@ -5333,6 +5391,7 @@ mp->int_name[mp_gtroffmode]=xstrdup("troffmode");
mp->int_name[mp_restore_clip_color]=xstrdup("restoreclipcolor");
mp->int_name[mp_output_template]=xstrdup("outputtemplate");
mp->int_name[mp_output_format]=xstrdup("outputformat");
+mp->int_name[mp_job_name]=xstrdup("jobname");
@ The following procedure, which is called just before \MP\ initializes its
input and output, establishes the initial values of the date and time.
@@ -5347,6 +5406,8 @@ static void mp_fix_date_and_time (MP mp) {
struct tm *tmptr = localtime (&aclock);
mp->internal[mp_time]=
(tmptr->tm_hour*60+tmptr->tm_min)*unity; /* minutes since midnight */
+ mp->internal[mp_hour]= (tmptr->tm_hour)*unity; /* hours since midnight */
+ mp->internal[mp_minute]= (tmptr->tm_min)*unity; /* minutes since the hour */
mp->internal[mp_day]=(tmptr->tm_mday)*unity; /* fourth day of the month */
mp->internal[mp_month]=(tmptr->tm_mon+1)*unity; /* seventh month of the year */
mp->internal[mp_year]=(tmptr->tm_year+1900)*unity; /* Anno Domini */
@@ -5576,6 +5637,24 @@ eq_type(frozen_right_delimiter)=right_delimiter;
@ @<Check the ``constant'' values...@>=
if ( hash_end+mp->max_internal>max_halfword ) mp->bad=17;
+@ The value of |hash_prime| should be roughly 85\pct! of |hash_size|, and it
+should be a prime number. The theory of hashing tells us to expect fewer
+than two table probes, on the average, when the search is successful.
+[See J.~S. Vitter, {\sl Journal of the ACM\/ \bf30} (1983), 231--258.]
+@^Vitter, Jeffrey Scott@>
+
+@c
+static integer mp_compute_hash (MP mp, const char *s, int l) {
+ integer k;
+ integer h = *s;
+ for (k=1;k<l;k++){
+ h=h+h+(*(s+k));
+ while ( h>=mp->hash_prime ) h=h-mp->hash_prime;
+ }
+ return h;
+}
+
+
@ Here is the subroutine that searches the hash table for an identifier
that matches a given string of length~|l| appearing in |buffer[j..
(j+l-1)]|. If the identifier is not found, it is inserted; hence it
@@ -5630,19 +5709,9 @@ incr(mp->st_count);
break;
}
+@ @<Compute the hash code |h|@>=
+h=mp_compute_hash(mp, (char *)mp->buffer+j, l)
-@ The value of |hash_prime| should be roughly 85\pct! of |hash_size|, and it
-should be a prime number. The theory of hashing tells us to expect fewer
-than two table probes, on the average, when the search is successful.
-[See J.~S. Vitter, {\sl Journal of the ACM\/ \bf30} (1983), 231--258.]
-@^Vitter, Jeffrey Scott@>
-
-@<Compute the hash code |h|@>=
-h=mp->buffer[j];
-for (k=j+1;k<j+l;k++){
- h=h+h+mp->buffer[k];
- while ( h>=mp->hash_prime ) h=h-mp->hash_prime;
-}
@ @<Search |eqtb| for equivalents equal to |p|@>=
for (q=1;q<=hash_end;q++) {
@@ -6874,8 +6943,11 @@ third kind.
static void mp_save_internal (MP mp,halfword q) {
pointer p; /* new item for the save stack */
if ( mp->save_ptr!=null ){
- p=mp_get_node(mp, save_node_size); mp_info(p)=hash_end+q;
- mp_link(p)=mp->save_ptr; value(p)=mp->internal[q]; mp->save_ptr=p;
+ p=mp_get_node(mp, save_node_size);
+ mp_info(p)=hash_end+q;
+ mp_link(p)=mp->save_ptr;
+ value(p)=mp->internal[q];
+ mp->save_ptr=p;
}
}
@@ -6891,16 +6963,29 @@ static void mp_unsave (MP mp) {
q=mp_info(mp->save_ptr);
if ( q>hash_end ) {
if ( mp->internal[mp_tracing_restores]>0 ) {
- mp_begin_diagnostic(mp); mp_print_nl(mp, "{restoring ");
- mp_print(mp, mp->int_name[q-(hash_end)]); mp_print_char(mp, xord('='));
- mp_print_scaled(mp, value(mp->save_ptr)); mp_print_char(mp, xord('}'));
+ mp_begin_diagnostic(mp);
+ mp_print_nl(mp, "{restoring ");
+ mp_print(mp, mp->int_name[q-(hash_end)]);
+ mp_print_char(mp, xord('='));
+ if (mp->int_type[q-(hash_end)]==mp_known) {
+ mp_print_scaled(mp, value(mp->save_ptr));
+ } else if (mp->int_type[q-(hash_end)]==mp_string_type) {
+ char *s = mp_str(mp, value(mp->save_ptr));
+ mp_print(mp, s);
+ free(s);
+ } else {
+ mp_confusion(mp,"internal_restore");
+ }
+ mp_print_char(mp, xord('}'));
mp_end_diagnostic(mp, false);
}
mp->internal[q-(hash_end)]=value(mp->save_ptr);
} else {
if ( mp->internal[mp_tracing_restores]>0 ) {
- mp_begin_diagnostic(mp); mp_print_nl(mp, "{restoring ");
- mp_print_text(q); mp_print_char(mp, xord('}'));
+ mp_begin_diagnostic(mp);
+ mp_print_nl(mp, "{restoring ");
+ mp_print_text(q);
+ mp_print_char(mp, xord('}'));
mp_end_diagnostic(mp, false);
}
mp_clear_symbol(mp, q,false);
@@ -7244,6 +7329,22 @@ static mp_knot *mp_export_knot (MP mp,pointer p) {
gr_originator(q) = (unsigned char)mp_originator(p);
return q;
}
+static pointer mp_import_knot (MP mp, mp_knot *q) {
+ pointer p; /* the copy */
+ if (q==NULL)
+ return null;
+ p=mp_get_node(mp, knot_node_size);
+ mp_left_type(p) = gr_left_type(q);
+ mp_right_type(p) = gr_right_type(q);
+ mp_x_coord(p) = gr_x_coord(q);
+ mp_y_coord(p) = gr_y_coord(q);
+ mp_left_x(p) = gr_left_x(q);
+ mp_left_y(p) = gr_left_y(q);
+ mp_right_x(p) = gr_right_x(q);
+ mp_right_y(p) = gr_right_y(q);
+ mp_originator(p) = gr_originator(q);
+ return p;
+}
@ The |export_knot_list| routine therefore also makes a clone
of a given path.
@@ -7264,6 +7365,21 @@ static mp_knot *mp_export_knot_list (MP mp, pointer p) {
gr_next_knot(qq)=q;
return q;
}
+static pointer mp_import_knot_list (MP mp, mp_knot *q) {
+ mp_knot *qq; /* for list manipulation */
+ pointer p, pp; /* for list manipulation */
+ if (q==NULL)
+ return null;
+ p=mp_import_knot(mp, q);
+ pp=p; qq=gr_link(q);
+ while ( qq!=q ) {
+ mp_link(pp)=mp_import_knot(mp, qq);
+ qq=gr_next_knot(qq);
+ pp=mp_link(pp);
+ }
+ mp_link(pp)=p;
+ return p;
+}
@ Similarly, there's a way to copy the {\sl reverse\/} of a path. This procedure
@@ -16281,9 +16397,11 @@ void mp_ptr_scan_file (MP mp, char *s) {
}
-@ The global variable |job_name| contains the file name that was first
-\&{input} by the user. This name is extended by `\.{.log}' and `\.{ps}' and
-`\.{.mem}' and `\.{.tfm}' in order to make the names of \MP's output files.
+@ The option variable |job_name| contains the file name that was first
+\&{input} by the user. This name is used to initialize the |job_name| global
+as well as the |mp_job_name| internal, and is extended by `\.{.log}' and
+`\.{ps}' and `\.{.mem}' and `\.{.tfm}' in order to make the names of \MP's
+output files.
@<Glob...@>=
boolean log_opened; /* has the transcript file been opened? */
@@ -16312,6 +16430,17 @@ if (opt->noninteractive && opt->ini_version) {
}
mp->log_opened=false;
+@ Cannot do this earlier because at the |@<Allocate or ...@>|, the string
+pool is not yet initialized.
+
+@<Fix up |mp->internal[mp_job_name]|@>=
+if (mp->job_name != NULL) {
+ if (mp->internal[mp_job_name]!=0)
+ delete_str_ref(mp->internal[mp_job_name]);
+ mp->internal[mp_job_name]=mp_rts(mp,mp->job_name);
+}
+
+
@ @<Dealloc variables@>=
xfree(mp->job_name);
@@ -16354,7 +16483,11 @@ void mp_prompt_file_name (MP mp, const char * s, const char * e) ;
print_err("I can\'t write on file `");
@.I can't write on file x@>
}
- mp_print_file_name(mp, mp->cur_name,mp->cur_area,mp->cur_ext);
+ if (strcmp(s,"file name for output")==0) {
+ mp_print(mp, mp->output_file);
+ } else {
+ mp_print_file_name(mp, mp->cur_name,mp->cur_area,mp->cur_ext);
+ }
mp_print(mp, "'.");
if (strcmp(e,"")==0)
mp_show_context(mp);
@@ -16400,6 +16533,7 @@ it catch up to what has previously been printed on the terminal.
old_setting=mp->selector;
if ( mp->job_name==NULL ) {
mp->job_name=xstrdup("mpout");
+ @<Fix up |mp->internal[mp_job_name]|@>;
}
mp_pack_job_name(mp,".log");
while ( ! mp_a_open_out(mp, &mp->log_file, mp_filetype_log) ) {
@@ -16414,7 +16548,7 @@ it catch up to what has previously been printed on the terminal.
mp_print_nl(mp, "**");
@.**@>
l=mp->input_stack[0].limit_field-1; /* last position of first line */
- for (k=0;k<=l;k++) mp_print_str(mp, mp->buffer[k]);
+ for (k=1;k<=l;k++) mp_print_str(mp, mp->buffer[k]);
mp_print_ln(mp); /* now the transcript file contains the first line of input */
}
mp->selector=old_setting+2; /* |log_only| or |term_and_log| */
@@ -16454,8 +16588,9 @@ this file.
mp_print_char(mp, xord(' '));
mp_print_int(mp, mp_round_unscaled(mp, mp->internal[mp_year]));
mp_print_char(mp, xord(' '));
- m=mp_round_unscaled(mp, mp->internal[mp_time]);
- mp_print_dd(mp, m / 60); mp_print_char(mp, xord(':')); mp_print_dd(mp, m % 60);
+ mp_print_dd(mp, mp_round_unscaled(mp, mp->internal[mp_hour]));
+ mp_print_char(mp, xord(':'));
+ mp_print_dd(mp, mp_round_unscaled(mp, mp->internal[mp_minute]));
}
@ The |try_extension| function tries to open an input file determined by
@@ -16498,6 +16633,7 @@ when an `\.{input}' command is being processed.
fname = xstrdup(mp->name_of_file);
if ( mp->job_name==NULL ) {
mp->job_name=xstrdup(mp->cur_name);
+ @<Fix up |mp->internal[mp_job_name]|@>;
mp_open_log_file(mp);
} /* |open_log_file| doesn't |show_context|, so |limit|
and |loc| needn't be set to meaningful values yet */
@@ -16604,7 +16740,7 @@ int mp_run_make_mpx (MP mp, char *origname, char *mtxname) {
origname = mp_xstrdup(mp,mp->name_of_file);
*(origname+strlen(origname)-1)=0; /* drop the x */
if (!(mp->run_make_mpx)(mp, origname, mp->name_of_file))
- goto NOT_FOUND
+ goto NOT_FOUND
@ @<Explain that the \.{MPX} file can't be read and |succumb|@>=
if ( mp->interaction==mp_error_stop_mode ) wake_up_terminal;
@@ -16617,6 +16753,7 @@ help4("The two files given above are one of your source files",
"and an auxiliary file I need to read to find out what your",
"btex..etex blocks mean. If you don't know why I had trouble,",
"try running it manually through MPtoTeX, TeX, and DVItoMP");
+xfree(origname);
succumb;
@ The last file-opening commands are for files accessed via the \&{readfrom}
@@ -16965,6 +17102,7 @@ case mp_vacuous:mp_print(mp, "mp_vacuous"); break;
case mp_boolean_type:
if ( v==true_code ) mp_print(mp, "true"); else mp_print(mp, "false");
break;
+case mp_internal_type:
case unknown_types: case mp_numeric_type:
@<Display a variable that's been declared but not defined@>;
break;
@@ -17037,8 +17175,8 @@ the ring consists entirely of capsules.
{ mp_print_type(mp, t);
if ( v!=null )
{ mp_print_char(mp, xord(' '));
- while ( (mp_name_type(v)==mp_capsule) && (v!=p) ) v=value(v);
- mp_print_variable_name(mp, v);
+ while ( (mp_name_type(v)==mp_capsule) && (v!=p) ) v=value(v);
+ mp_print_variable_name(mp, v);
};
}
@@ -17729,12 +17867,19 @@ of the save stack, as described earlier.)
mp->cur_exp=mp_get_avail(mp);
mp_info(mp->cur_exp)=q+hash_end; mp->cur_type=mp_token_list;
goto DONE;
+ } else {
+ if (mp->int_type[q]==mp_internal_type)
+ mp->int_type[q] = mp_known;
}
mp_back_input(mp);
+ } else {
+ if (mp->int_type[q]==mp_internal_type)
+ mp->int_type[q] = mp_known;
}
- mp->cur_type=mp_known; mp->cur_exp=mp->internal[q];
- if (q == mp_output_format || q == mp_output_template)
- mp->cur_type=mp_string_type;
+ mp->cur_exp=mp->internal[q];
+ if (mp->int_type[q]==mp_string_type)
+ add_str_ref(mp->cur_exp);
+ mp->cur_type=mp->int_type[q];
}
@ The most difficult part of |scan_primary| has been saved for last, since
@@ -18695,8 +18840,6 @@ mp_primitive(mp, "nullpicture",nullary,null_picture_code);
@:null_picture_}{\&{nullpicture} primitive@>
mp_primitive(mp, "nullpen",nullary,null_pen_code);
@:null_pen_}{\&{nullpen} primitive@>
-mp_primitive(mp, "jobname",nullary,job_name_op);
-@:job_name_}{\&{jobname} primitive@>
mp_primitive(mp, "readstring",nullary,read_string_op);
@:read_string_}{\&{readstring} primitive@>
mp_primitive(mp, "pencircle",nullary,pen_circle);
@@ -18887,6 +19030,8 @@ mp_primitive(mp, "intersectiontimes",tertiary_binary,intersect);
@:intersection_times_}{\&{intersectiontimes} primitive@>
mp_primitive(mp, "envelope",primary_binary,envelope_of);
@:envelope_}{\&{envelope} primitive@>
+mp_primitive(mp, "glyph",primary_binary,glyph_infont);
+@:glyph_infont_}{\&{envelope} primitive@>
@ @<Cases of |print_cmd...@>=
case nullary:
@@ -18929,10 +19074,6 @@ static void mp_do_nullary (MP mp,quarterword c) {
case pen_circle:
mp->cur_type=mp_pen_type; mp->cur_exp=mp_get_pen_circle(mp, unity);
break;
- case job_name_op:
- if ( mp->job_name==NULL ) mp_open_log_file(mp);
- mp->cur_type=mp_string_type; mp->cur_exp=rts(mp->job_name);
- break;
case mp_version:
mp->cur_type=mp_string_type;
mp->cur_exp=intern(metapost_version) ;
@@ -21374,6 +21515,14 @@ case envelope_of:
else
mp_set_up_envelope(mp, p);
break;
+case glyph_infont:
+ if ( (mp_type(p) != mp_string_type &&
+ mp_type(p) != mp_known) || (mp->cur_type != mp_string_type) )
+ mp_bad_binary(mp, p,glyph_infont);
+ else
+ mp_set_up_glyph_infont(mp, p);
+ break;
+ break;
@ @<Declare binary action...@>=
static void mp_set_up_offset (MP mp,pointer p) {
@@ -21409,6 +21558,44 @@ static void mp_set_up_envelope (MP mp,pointer p) {
mp->cur_type = mp_path_type;
}
+
+@ This is pretty straightfoward. The one silly thing is that
+the output of |mp_ps_do_font_charstring| has to be un-exported.
+
+@<Declare binary action...@>=
+static void mp_set_up_glyph_infont (MP mp, pointer p) {
+ mp_edge_object *h = NULL;
+ mp_ps_font *f = NULL;
+ char *n = mp_str(mp, mp->cur_exp);
+ f = mp_ps_font_parse(mp, mp_find_font(mp, n));
+ if (f!=NULL) {
+ if (mp_type(p) == mp_known) {
+ int v = mp_round_unscaled(mp,value(p));
+ if (v<0 || v>255) {
+ print_err ("glyph index too high (");
+ mp_print_int(mp,v);
+ mp_print(mp,")");
+ mp_error(mp);
+ } else {
+ h = mp_ps_font_charstring (mp,f,v);
+ }
+ } else {
+ n = mp_str(mp, value(p));
+ delete_str_ref(value(p));
+ h = mp_ps_do_font_charstring (mp,f,n);
+ free(n);
+ }
+ mp_ps_font_free(mp,f);
+ }
+ if (h!=NULL) {
+ mp->cur_exp=mp_gr_unexport(mp, h);
+ } else {
+ mp->cur_exp=mp_get_node(mp, edge_header_size);
+ mp_init_edges(mp, mp->cur_exp);
+ }
+ mp->cur_type=mp_picture_type;
+}
+
@ @<Declare binary action...@>=
static void mp_find_point (MP mp,scaled v, quarterword c) {
pointer p; /* the path */
@@ -21478,7 +21665,7 @@ case intersect:
@ @<Additional cases of bin...@>=
case in_font:
- if ( (mp->cur_type!=mp_string_type)||(mp_type(p)!=mp_string_type))
+ if ( (mp->cur_type!=mp_string_type)||mp_type(p)!=mp_string_type)
mp_bad_binary(mp, p,in_font);
else { mp_do_infont(mp, p); binary_return; }
break;
@@ -21712,16 +21899,42 @@ void mp_do_assignment (MP mp) {
@ @<Assign the current expression to an internal variable@>=
if ( mp->cur_type==mp_known || mp->cur_type==mp_string_type ) {
- if (mp->cur_type==mp_string_type)
- add_str_ref(mp->cur_exp);
- mp->internal[mp_info(lhs)-(hash_end)]=mp->cur_exp;
+ if (mp->int_type[mp_info(lhs)-(hash_end)]==mp_internal_type) {
+ mp->int_type[mp_info(lhs)-(hash_end)]=mp->cur_type;
+ }
+ if (mp->cur_type==mp_string_type) {
+ if (mp->int_type[mp_info(lhs)-(hash_end)]!=mp->cur_type) {
+ exp_err("Internal quantity `");
+@.Internal quantity...@>
+ mp_print(mp, mp->int_name[mp_info(lhs)-(hash_end)]);
+ mp_print(mp, "' must receive a known numeric value");
+ help2("I can\'t set this internal quantity to anything but a known",
+ "numeric value, so I'll have to ignore this assignment.");
+ mp_put_get_error(mp);
+ } else {
+ add_str_ref(mp->cur_exp);
+ mp->internal[mp_info(lhs)-(hash_end)]=mp->cur_exp;
+ }
+ } else { /* mp_known */
+ if (mp->int_type[mp_info(lhs)-(hash_end)]!=mp->cur_type) {
+ exp_err("Internal quantity `");
+@.Internal quantity...@>
+ mp_print(mp, mp->int_name[mp_info(lhs)-(hash_end)]);
+ mp_print(mp, "' must receive a known string");
+ help2("I can\'t set this internal quantity to anything but a known",
+ "string, so I'll have to ignore this assignment.");
+ mp_put_get_error(mp);
+ } else {
+ mp->internal[mp_info(lhs)-(hash_end)]=mp->cur_exp;
+ }
+ }
} else {
exp_err("Internal quantity `");
@.Internal quantity...@>
mp_print(mp, mp->int_name[mp_info(lhs)-(hash_end)]);
- mp_print(mp, "' must receive a known value");
- help2("I can\'t set an internal quantity to anything but a known",
- "numeric value, so I'll have to ignore this assignment.");
+ mp_print(mp, "' must receive a known numeric or string");
+ help2("I can\'t set an internal quantity to anything but a known string",
+ "or known numeric value, so I'll have to ignore this assignment.");
mp_put_get_error(mp);
}
@@ -22118,6 +22331,66 @@ int mp_run (MP mp) {
return mp->history;
}
+@ This function allows setting of internals from an external
+source (like the command line or a controlling application).
+
+It accepts two |char *|'s, even for numeric assignments when
+it calls |atoi| to get an integer from the start of the string.
+
+@c
+void mp_set_internal (MP mp, char *n, char *v, int isstring) {
+ integer l = strlen(n);
+ char err[256];
+ char *errid = NULL;
+ if (l>0) {
+ integer h = mp_compute_hash(mp, n,l);
+ pointer p = h+hash_base; /* we start searching here */
+ while (true) {
+ if (text(p)>0 && length(text(p))==l &&
+ mp_str_eq_cstr(mp, text(p),n)) {
+ if (eq_type(p)==internal_quantity) {
+ if (mp->int_type[equiv(p)]==mp_internal_type) {
+ mp->int_type[equiv(p)] = (isstring ? mp_string_type : mp_known);
+ }
+ if ((mp->int_type[equiv(p)]==mp_string_type) && (isstring)) {
+ mp->internal[equiv(p)] = mp_rts(mp,v);
+ } else if ((mp->int_type[equiv(p)]==mp_known) && (!isstring)) {
+ scaled test = (scaled)atoi(v);
+ if (test>16383 ) {
+ errid = "value is too large";
+ } else if (test<-16383) {
+ errid = "value is too small";
+ } else {
+ mp->internal[equiv(p)] = test*unity;
+ }
+ } else {
+ errid = "value has the wrong type";
+ }
+ } else {
+ errid = "variable is not an internal";
+ }
+ break;
+ }
+ if ( mp_next(p)==0 ) {
+ errid = "variable does not exist";
+ break;
+ }
+ p=mp_next(p);
+ }
+ }
+ if (errid != NULL) {
+ if (isstring) {
+ mp_snprintf(err,256,"%s=\"%s\": %s, assignment ignored.",n,v, errid);
+ } else {
+ mp_snprintf(err,256,"%s=%d: %s, assignment ignored.",n,atoi(v),errid);
+ }
+ mp_warn(mp,err);
+ }
+}
+
+@ @<Exported function headers@>=
+void mp_set_internal (MP mp, char *n, char *v, int isstring);
+
@ For |mp_execute|, we need to define a structure to store the
redirected input and output. This structure holds the five relevant
streams: the three informational output streams, the PostScript
@@ -22839,22 +23112,27 @@ void mp_grow_internals (MP mp, int l);
void mp_grow_internals (MP mp, int l) {
scaled *internal;
char * *int_name;
+ int *int_type;
int k;
if ( hash_end+l>max_halfword ) {
mp_confusion(mp, "out of memory space"); /* can't be reached */
}
int_name = xmalloc ((l+1),sizeof(char *));
+ int_type = xmalloc ((l+1),sizeof(int));
internal = xmalloc ((l+1),sizeof(scaled));
for (k=0;k<=l; k++ ) {
if (k<=mp->max_internal) {
internal[k]=mp->internal[k];
int_name[k]=mp->int_name[k];
+ int_type[k]=mp->int_type[k];
} else {
internal[k]=0;
int_name[k]=NULL;
+ int_type[k]=mp_internal_type;
}
}
- xfree(mp->internal); xfree(mp->int_name);
+ xfree(mp->internal); xfree(mp->int_name); xfree(mp->int_type);
+ mp->int_type = int_type;
mp->int_name = int_name;
mp->internal = internal;
mp->max_internal = l;
@@ -22882,6 +23160,7 @@ for (k=0;k<=mp->max_internal;k++) {
}
xfree(mp->internal);
xfree(mp->int_name);
+xfree(mp->int_type);
@ The various `\&{show}' commands are distinguished by modifier fields
@@ -23760,7 +24039,9 @@ mp->start_sym=0;
@d err_message_code 1
@d err_help_code 2
@d filename_template_code 3
-@d print_with_leading_zeroes(A) g = mp->pool_ptr;
+@d print_with_leading_zeroes(A,B) do {
+ integer g = mp->pool_ptr;
+ integer f = (B);
mp_print_int(mp, (A)); g = mp->pool_ptr-g;
if ( f>g ) {
mp->pool_ptr = mp->pool_ptr - g;
@@ -23770,7 +24051,8 @@ mp->start_sym=0;
};
mp_print_int(mp, (A));
};
- f = 0
+ f = 0;
+ } while (0)
@<Put each...@>=
mp_primitive(mp, "message",message_command,message_code);
@@ -25516,13 +25798,22 @@ etcetera to make it worthwile to move the code to |psout.w|.
void mp_open_output_file (MP mp) ;
@ @c
+static void mp_append_to_template (MP mp, integer ff, integer c) {
+ if (mp->int_type[c]==mp_string_type) {
+ char *ss = str(mp->internal[c]);
+ mp_print(mp,ss);
+ mp_xfree(ss);
+ } else if (mp->int_type[c]==mp_known) {
+ integer cc = mp_round_unscaled(mp, mp->internal[c]);
+ print_with_leading_zeroes(cc, ff);
+ }
+}
static char *mp_set_output_file_name (MP mp, integer c) {
char *ss = NULL; /* filename extension proposal */
char *nn = NULL; /* temp string for str() */
unsigned old_setting; /* previous |selector| setting */
pool_pointer i; /* indexes into |filename_template| */
- integer cc; /* a temporary integer for template building */
- integer f,g=0; /* field widths */
+ integer f; /* field width */
if ( mp->job_name==NULL ) mp_open_log_file(mp);
if ( mp->internal[mp_output_template]==0) {
char *s; /* a file extension derived from |c| */
@@ -25535,48 +25826,108 @@ static char *mp_set_output_file_name (MP mp, integer c) {
ss = xstrdup(mp->name_of_file);
} else { /* initializations */
str_number s, n; /* a file extension derived from |c| */
+ scaled saved_char_code = mp->internal[mp_char_code];
+ mp->internal[mp_char_code] = (c*unity);
+ if (mp->internal[mp_job_name]==0) {
+ if ( mp->job_name==NULL ) {
+ mp->job_name=xstrdup("mpout");
+ }
+ @<Fix up |mp->internal[mp_job_name]|@>;
+ }
old_setting=mp->selector;
mp->selector=new_string;
- f = 0;
i = mp->str_start[mp->internal[mp_output_template]];
n = null_str; /* initialize */
while ( i<str_stop(mp->internal[mp_output_template]) ) {
+ f=0;
if ( mp->str_pool[i]=='%' ) {
CONTINUE:
incr(i);
if ( i<str_stop(mp->internal[mp_output_template]) ) {
- if ( mp->str_pool[i]=='j' ) {
- mp_print(mp, mp->job_name);
- } else if ( mp->str_pool[i]=='o' ) {
- { char *s;
- s = str(mp->internal[mp_output_format]);
- mp_print(mp, s);
- mp_xfree(s);
- }
- } else if ( mp->str_pool[i]=='d' ) {
- cc= mp_round_unscaled(mp, mp->internal[mp_day]);
- print_with_leading_zeroes(cc);
- } else if ( mp->str_pool[i]=='m' ) {
- cc= mp_round_unscaled(mp, mp->internal[mp_month]);
- print_with_leading_zeroes(cc);
- } else if ( mp->str_pool[i]=='y' ) {
- cc= mp_round_unscaled(mp, mp->internal[mp_year]);
- print_with_leading_zeroes(cc);
- } else if ( mp->str_pool[i]=='H' ) {
- cc= mp_round_unscaled(mp, mp->internal[mp_time]) / 60;
- print_with_leading_zeroes(cc);
- } else if ( mp->str_pool[i]=='M' ) {
- cc= mp_round_unscaled(mp, mp->internal[mp_time]) % 60;
- print_with_leading_zeroes(cc);
- } else if ( mp->str_pool[i]=='c' ) {
- if ( c<0 ) mp_print(mp, "ps");
- else print_with_leading_zeroes(c);
- } else if ( (mp->str_pool[i]>='0') &&
- (mp->str_pool[i]<='9') ) {
+ switch (mp->str_pool[i]) {
+ case 'j':
+ mp_append_to_template(mp,f,mp_job_name);
+ break;
+ case 'c':
+ mp_append_to_template(mp,f,mp_char_code);
+ break;
+ case 'o':
+ mp_append_to_template(mp,f,mp_output_format);
+ break;
+ case 'd':
+ mp_append_to_template(mp,f,mp_day);
+ break;
+ case 'm':
+ mp_append_to_template(mp,f,mp_month);
+ break;
+ case 'y':
+ mp_append_to_template(mp,f,mp_year);
+ break;
+ case 'H':
+ mp_append_to_template(mp,f,mp_hour);
+ break;
+ case 'M':
+ mp_append_to_template(mp,f,mp_minute);
+ break;
+ case '{':
+ {
+ /* look up a name */
+ integer l=0;
+ integer frst = i+1;
+ while ( i<str_stop(mp->internal[mp_output_template]) ) {
+ i++;
+ if (mp->str_pool[i] == '}')
+ break;
+ l++;
+ }
+ if (l>0) {
+ integer h = mp_compute_hash(mp, (char *)(mp->str_pool+frst),l);
+ pointer p=h+hash_base; /* we start searching here */
+ char *id = xmalloc(mp, (l+1));
+ strncpy(id,(char *)(mp->str_pool+frst),l);
+ *(id+l)=0;
+ while (true) {
+ if (text(p)>0 && length(text(p))==l &&
+ mp_str_eq_cstr(mp, text(p),id)) {
+ if (eq_type(p)==internal_quantity) {
+ mp_append_to_template(mp,f,equiv(p));
+ } else {
+ char err[256];
+ mp_snprintf(err,256,
+ "requested identifier (%s) in outputtemplate is not an internal.",id);
+ mp_warn(mp,err);
+ }
+ break;
+ }
+ if ( mp_next(p)==0 ) {
+ char err[256];
+ mp_snprintf(err,256,
+ "requested identifier (%s) in outputtemplate not found.",id);
+ mp_warn(mp,err);
+ break;
+ }
+ p=mp_next(p);
+ }
+ free(id);
+ }
+ }
+ break;
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
if ( (f<10) )
f = (f*10) + mp->str_pool[i]-'0';
goto CONTINUE;
- } else {
+ break;
+ case '%':
+ mp_print_str(mp, mp->str_pool[i]);
+ break;
+ default:
+ {
+ char err[256];
+ mp_snprintf(err,256,
+ "requested format (%c) in outputtemplate is unknown.",mp->str_pool[i]);
+ mp_warn(mp,err);
+ }
mp_print_str(mp, mp->str_pool[i]);
}
}
@@ -25589,6 +25940,7 @@ static char *mp_set_output_file_name (MP mp, integer c) {
incr(i);
}
s = mp_make_string(mp);
+ mp->internal[mp_char_code] = saved_char_code;
mp->selector= old_setting;
if (length(n)==0) {
n=s;
@@ -25597,7 +25949,7 @@ static char *mp_set_output_file_name (MP mp, integer c) {
ss = str(s);
nn = str(n);
mp_pack_file_name(mp, nn,"",ss);
- free(nn);
+ mp_xfree(nn);
delete_str_ref(n);
delete_str_ref(s);
}
@@ -25608,7 +25960,7 @@ static char * mp_get_output_file_name (MP mp) {
char *f;
char *saved_name; /* saved |name_of_file| */
saved_name = xstrdup(mp->name_of_file);
- f = xstrdup(mp_set_output_file_name(mp, mp_round_unscaled(mp, mp->internal[mp_char_code])));
+ f = mp_set_output_file_name(mp, mp_round_unscaled(mp, mp->internal[mp_char_code]));
mp_pack_file_name(mp, saved_name,NULL,NULL);
free(saved_name);
return f;
@@ -25920,8 +26272,56 @@ struct mp_edge_object *mp_gr_export(MP mp, pointer h) {
return hh;
}
+@ This function is only used for the |glyph| operator, so
+it takes quite a few shortcuts for cases that cannot appear
+in the output of |mp_ps_font_charstring|.
+
+@c
+pointer mp_gr_unexport(MP mp, struct mp_edge_object *hh) {
+ pointer h; /* the edge object */
+ pointer ph, pn; /* for adding items */
+ mp_graphic_object *p; /* the current graphical object */
+ h = mp_get_node(mp, edge_header_size);
+ mp_init_edges(mp, h);
+ ph = dummy_loc(h);
+ p = hh->body;
+ minx_val(h) = hh->minx;
+ miny_val(h) = hh->miny;
+ maxx_val(h) = hh->maxx;
+ maxy_val(h) = hh->maxy;
+ while ( p!=NULL ) {
+ switch (gr_type(p)) {
+ case mp_fill_code:
+ if ( gr_pen_p((mp_fill_object *)p)==NULL ) {
+ pn = mp_new_fill_node (mp, null);
+ mp_path_p(pn) = mp_import_knot_list(mp,gr_path_p((mp_fill_object *)p));
+ if (mp_new_turn_cycles(mp, mp_path_p(pn))<0) {
+ mp_color_model(pn)=mp_grey_model;
+ grey_val(pn) = unity;
+ }
+ mp_link(ph) = pn;
+ ph = mp_link(ph);
+ }
+ break;
+ case mp_stroked_code:
+ case mp_text_code:
+ case mp_start_clip_code:
+ case mp_stop_clip_code:
+ case mp_start_bounds_code:
+ case mp_stop_bounds_code:
+ case mp_special_code:
+ break;
+ } /* all cases are enumerated */
+ p=p->next;
+ }
+ mp_gr_toss_objects(hh);
+ return h;
+}
+
+
@ @<Declarations@>=
-static struct mp_edge_object *mp_gr_export(MP mp, int h);
+static struct mp_edge_object *mp_gr_export(MP mp, pointer h);
+static pointer mp_gr_unexport(MP mp, struct mp_edge_object *h);
@ This function is now nearly trivial.
@@ -25958,6 +26358,7 @@ void mp_shipout_backend (MP mp, pointer h) {
(mp->internal[mp_procset]/65536),
false);
}
+ mp_xfree(s);
mp_gr_toss_objects(hh);
}
diff --git a/Build/source/texk/web2c/mplibdir/mpost.w b/Build/source/texk/web2c/mplibdir/mpost.w
index 79ade1ead57..f0f19cf105a 100644
--- a/Build/source/texk/web2c/mplibdir/mpost.w
+++ b/Build/source/texk/web2c/mplibdir/mpost.w
@@ -1,4 +1,4 @@
-% $Id: mpost.w 892 2009-04-14 14:28:42Z taco $
+% $Id: mpost.w 941 2009-04-19 13:13:56Z taco $
%
% Copyright 2008 Taco Hoekwater.
%
@@ -22,7 +22,7 @@
\def\[#1]{#1.}
\pdfoutput=1
-@* \[1] Metapost executable.
+@*\MP\ executable.
Now that all of \MP\ is a library, a separate program is needed to
have our customary command-line interface.
@@ -242,8 +242,9 @@ void recorder_start(char *jobname) {
return kpse_find_file (nam, fmt, req);
}
-@ Invoke makempx (or troffmpx) to make sure there is an up-to-date
- .mpx file for a given .mp file. (Original from John Hobby 3/14/90)
+@ Invoke {\tt makempx} (or {\tt troffmpx}) to make sure there is an
+ up-to-date {\tt .mpx} file for a given {\tt .mp} file. (Original
+ from John Hobby 3/14/90)
@d default_args " --parse-first-line --interaction=nonstopmode"
@d TEX "tex"
@@ -471,6 +472,87 @@ static char *mpost_find_file(MP mp, const char *fname, const char *fmode, int ft
if (!nokpse)
options->find_file = mpost_find_file;
+@ The |mpost| program supports setting of internal values
+via a |-s| commandline switch. Since this switch is repeatable,
+a structure is needed to store the found values in, which is a
+simple linked list.
+
+@c
+typedef struct set_list_item {
+ int isstring;
+ char *name;
+ char *value;
+ struct set_list_item *next;
+} set_list_item ;
+
+@ Here is the global value that is the head of the list of |-s| options.
+@c
+struct set_list_item *set_list = NULL;
+
+@ And |internal_set_option| is the routine that fills in the linked
+list. The argument it receives starts at the first letter of the
+internal, and should contain an internal name, an equals sign,
+and the value (possibly in quotes) without any intervening spaces.
+
+Double quotes around the right hand side are needed to make sure that
+the right hand side is treated as a string assignment by MPlib later.
+These outer double quote characters are stripped, but no other string
+processing takes place.
+
+As a special hidden feature, a missing right hand side is treated as if it
+was the integer value |1|.
+
+@c
+void internal_set_option(const char *opt) {
+ struct set_list_item *itm;
+ char *s, *v;
+ int isstring = 0;
+ s = xstrdup(opt) ;
+ v = strstr(s,"=") ;
+ if (v==NULL) {
+ v="1";
+ } else {
+ *v='\0'; /* terminates |s| */
+ v++;
+ if (*v && *v=='"') {
+ isstring=1;
+ v++;
+ *(v+strlen(v)-1)= '\0';
+ }
+ }
+ if (s && v && strlen(s)>0) {
+ if (set_list == NULL) {
+ set_list = xmalloc(sizeof(struct set_list_item));
+ itm = set_list;
+ } else {
+ itm = set_list;
+ while (itm->next != NULL)
+ itm = itm->next;
+ itm->next = xmalloc(sizeof(struct set_list_item));
+ itm = itm->next;
+ }
+ itm->name = s;
+ itm->value = v;
+ itm->isstring = isstring;
+ itm->next = NULL;
+ }
+}
+
+@ After the initialization stage is done, the next function
+runs thourgh the list of options and feeds them to the MPlib
+function |mp_set_internal|.
+
+@c
+void run_set_list (MP mp) {
+ struct set_list_item *itm;
+ itm = set_list;
+ while (itm!=NULL) {
+ mp_set_internal(mp,itm->name,itm->value, itm->isstring);
+ itm = itm->next;
+ }
+}
+
+
@ @c
static void *mpost_open_file(MP mp, const char *fname, const char *fmode, int ftype) {
char realmode[3];
@@ -507,7 +589,7 @@ if (!nokpse)
options->open_file = mpost_open_file;
-@ At the moment, the command line is very simple.
+@ Parsing the commandline options.
@d option_is(A) ((strncmp(argv[a],"--" A, strlen(A)+2)==0) ||
(strncmp(argv[a],"-" A, strlen(A)+1)==0))
@@ -526,6 +608,20 @@ if (!nokpse)
}
if (option_is("ini")) {
ini_version_test = true;
+ } else if (option_is("s")) {
+ char *s_head = argv[a];
+ while (*s_head!='s') s_head++;
+ s_head++;
+ if (!*s_head) {
+ if (((a+1)<argc) && (*(argv[(a+1)])!='-')) {
+ internal_set_option(argv[++a]);
+ } else {
+ fprintf(stdout,"fatal error: %s: missing -s argument\n", argv[0]);
+ exit(EXIT_FAILURE);
+ }
+ } else {
+ internal_set_option(s_head);
+ }
} else if (option_is("debug")) {
debug = 1;
} else if (option_is ("kpathsea-debug")) {
@@ -572,7 +668,11 @@ if (!nokpse)
} else if (option_is("dvitomp")) {
dvitomp_only = 1;
} else if (option_is("help")) {
- @<Show help and exit@>;
+ if (dvitomp_only) {
+ @<Show short help and exit@>;
+ } else {
+ @<Show help and exit@>;
+ }
} else if (option_is("version")) {
@<Show version and exit@>;
} else if (option_is("8bit") ||
@@ -595,6 +695,40 @@ if (!nokpse)
}
@
+@<Read and set dvitomp command line options@>=
+{
+ char *mpost_optarg;
+ boolean ini_version_test = false;
+ while (++a<argc) {
+ mpost_optarg = strstr(argv[a],"=") ;
+ if (mpost_optarg!=NULL) {
+ mpost_optarg++;
+ if (*mpost_optarg == '\0') mpost_optarg=NULL;
+ }
+ if (option_is("debug")) {
+ debug = 1;
+ } else if (option_is ("kpathsea-debug")) {
+ if (mpost_optarg!=NULL)
+ kpathsea_debug |= atoi (mpost_optarg);
+ } else if (option_is ("progname")) {
+ user_progname = mpost_optarg;
+ } else if (option_is("no-kpathsea")) {
+ nokpse=true;
+ } else if (option_is("help")) {
+ @<Show short help and exit@>;
+ } else if (option_is("version")) {
+ @<Show version and exit@>;
+ } else if (option_is("")) {
+ fprintf(stdout,"fatal error: %s: unknown option %s\n", argv[0], argv[a]);
+ exit(EXIT_FAILURE);
+ } else {
+ break;
+ }
+ }
+ options->ini_version = (int)ini_version_test;
+}
+
+@
@<Show help...@>=
{
fprintf(stdout,
@@ -606,7 +740,8 @@ fprintf(stdout,
" MPNAME.tfm), where NNN are the character numbers generated.\n"
" Any remaining COMMANDS are processed as MetaPost input,\n"
" after MPNAME is read.\n\n"
-" With a --dvitomp argument, MetaPost acts as DVI-to-MPX converter only.\n\n");
+" With a --dvitomp argument, MetaPost acts as DVI-to-MPX converter only.\n"
+" Call MetaPost with --dvitomp --help for option explanations.\n\n");
fprintf(stdout,
" -ini be inimpost, for dumping mem files\n"
" -interaction=STRING set interaction mode (STRING=batchmode/nonstopmode/\n"
@@ -622,6 +757,29 @@ fprintf(stdout,
" -mem=MEMNAME or &MEMNAME use MEMNAME instead of program name or a %%& line\n"
" -recorder enable filename recorder\n"
" -troff set prologues:=1 and assume TEXPROGRAM is really troff\n"
+" -sINTERNAL=\"STRING\" set internal INTERNAL to the string value STRING\n"
+" -sINTERNAL=NUMBER set internal INTERNAL to the integer value NUMBER\n"
+" -help display this help and exit\n"
+" -version output version information and exit\n"
+"\n"
+"Email bug reports to mp-implementors@@tug.org.\n"
+"\n");
+ exit(EXIT_SUCCESS);
+}
+
+@
+@<Show short help...@>=
+{
+fprintf(stdout,
+"\n"
+"Usage: dvitomp DVINAME[.dvi] [MPXNAME[.mpx]]\n"
+" mpost --dvitomp DVINAME[.dvi] [MPXNAME[.mpx]]\n"
+"\n"
+" Convert a TeX DVI file to a MetaPost MPX file.\n\n");
+fprintf(stdout,
+" -progname=STRING set program name to STRING\n"
+" -kpathsea-debug=NUMBER set path searching debugging flags according to\n"
+" the bits of NUMBER\n"
" -help display this help and exit\n"
" -version output version information and exit\n"
"\n"
@@ -634,9 +792,11 @@ fprintf(stdout,
@<Show version...@>=
{
char *s = mp_metapost_version();
+if (dvitomp_only)
+ fprintf(stdout, "\n" "dvitomp %s\n", s);
+else
+ fprintf(stdout, "\n" "MetaPost %s\n", s);
fprintf(stdout,
-"\n"
-"MetaPost %s\n"
"Copyright 2008 AT&T Bell Laboratories.\n"
"There is NO warranty. Redistribution of this software is\n"
"covered by the terms of both the MetaPost copyright and\n"
@@ -645,7 +805,7 @@ fprintf(stdout,
"named COPYING, COPYING.LESSER and the MetaPost source.\n"
"Primary author of MetaPost: John Hobby.\n"
"Current maintainer of MetaPost: Taco Hoekwater.\n"
-"\n", s);
+"\n");
mpost_xfree(s);
exit(EXIT_SUCCESS);
}
@@ -878,11 +1038,16 @@ int main (int argc, char **argv) { /* |start_here| */
struct MP_options * options; /* instance options */
int a=0; /* argc counter */
boolean nokpse = false; /* switch to {\it not} enable kpse */
- char *user_progname = NULL; /* If the user overrides argv[0] with -progname. */
+ char *user_progname = NULL; /* If the user overrides |argv[0]| with {\tt -progname}. */
options = mp_options();
options->ini_version = (int)false;
options->print_found_names = (int)true;
- @<Read and set command line options@>;
+ if (strstr(argv[0], "dvitomp") != NULL) {
+ dvitomp_only=1;
+ @<Read and set dvitomp command line options@>;
+ } else {
+ @<Read and set command line options@>;
+ }
if (dvitomp_only) {
char *mpx = NULL, *dvi = NULL;
if (a==argc) {
@@ -893,9 +1058,13 @@ int main (int argc, char **argv) { /* |start_here| */
mpx = argv[a++];
}
}
- if (!nokpse)
- kpse_set_program_name("dvitomp", user_progname);
- exit (mpost_run_dvitomp(dvi, mpx));
+ if (dvi == NULL) {
+ @<Show short help and exit@>;
+ } else {
+ if (!nokpse)
+ kpse_set_program_name("dvitomp", user_progname);
+ exit (mpost_run_dvitomp(dvi, mpx));
+ }
}
@= /*@@-nullpass@@*/ @>
@@ -932,6 +1101,9 @@ int main (int argc, char **argv) { /* |start_here| */
history = mp_status(mp);
if (history!=0)
exit(history);
+ if (set_list!=NULL) {
+ run_set_list(mp);
+ }
history = mp_run(mp);
(void)mp_finish(mp);
exit(history);
diff --git a/Build/source/texk/web2c/mplibdir/mpxout.w b/Build/source/texk/web2c/mplibdir/mpxout.w
index 283f1c9c41c..57faa4439a3 100644
--- a/Build/source/texk/web2c/mplibdir/mpxout.w
+++ b/Build/source/texk/web2c/mplibdir/mpxout.w
@@ -1,4 +1,4 @@
-% $Id: mpxout.w 892 2009-04-14 14:28:42Z taco $
+% $Id: mpxout.w 973 2009-04-21 15:28:57Z taco $
%
% Copyright 2008 Taco Hoekwater.
%
@@ -108,7 +108,6 @@ in order to prevent name clashes.
#define PI 3.14159265358979323846
#endif
#include "avl.h"
-extern void *avl_probe (avl_tree t, void *p);
#include "mpxout.h"
@h
@@ -259,6 +258,8 @@ jmp_buf jump_buf;
static void mpx_abort(MPX mpx, char *msg, ...) {
va_list ap;
va_start(ap, msg);
+ fprintf(stderr, "fatal: ");
+ (void)vfprintf(stderr, msg, ap);
mpx_printf(mpx, "fatal", msg, ap);
va_end(ap);
mpx->history=mpx_fatal_error;
@@ -1204,6 +1205,11 @@ for (k=1;k<=3+lh;k++) {
else
mpx->tfm_check_sum=(((mpx->b0-256)*(int)(256)+mpx->b1)*256+mpx->b2)*256+mpx->b3;
}
+ if ( k==5 ) {
+ if (mpx->mode == mpx_troff_mode) {
+ mpx->font_design_size[f]=(((mpx->b0*(int)(256)+mpx->b1)*256+mpx->b2)*256+mpx->b3)/(65536.0*16);
+ }
+ }
}
@ @<Store character-width indices...@>=
@@ -1655,9 +1661,10 @@ static void mpx_finish_last_char (MPX mpx) {
} else {
mpx_end_char_string(mpx,47);
}
- fprintf(mpx->mpxfile, ")infont n%d", mpx->font_num[mpx->str_f]);
+ fprintf(mpx->mpxfile, "), _n%d", mpx->str_f);
+ fprintf(mpx->mpxfile, ",%.5f,%.4f,%.4f)", (m*1.00375), (x/100.0), y);
mpx_slant_and_ht(mpx);
- fprintf(mpx->mpxfile, ",%.5f,%.4f,%.4f);\n", (m*1.00375), x, y);
+ fprintf(mpx->mpxfile, ";\n");
}
mpx->str_f=-1;
}
@@ -2558,7 +2565,7 @@ typedef struct {
@ @c
static int mpx_comp_name (void *p, const void *pa, const void *pb) {
(void)p;
- return strcmp (((const avl_entry *) pa)->name,
+ return strcmp (((const avl_entry *) pa)->name,
((const avl_entry *) pb)->name);
}
static void *destroy_avl_entry (void *pa) {
@@ -2598,12 +2605,12 @@ calls where needed, but it is wise to have a wrapper around |avl_probe|
to check for memory errors.
@c
-static avl_entry * mpx_avl_probe(MPX mpx, avl_tree tab, avl_entry *p) {
- avl_entry *r = (avl_entry *)avl_probe(tab,p);
- if (r==NULL)
- mpx_abort(mpx,"Memory allocation failure");
- return r;
-
+static void mpx_avl_probe(MPX mpx, avl_tree tab, avl_entry *p) {
+ avl_entry *r = (avl_entry *)avl_find(p, tab);
+ if (r==NULL) {
+ if (avl_ins (p, tab, avl_false)<0)
+ mpx_abort(mpx,"Memory allocation failure");
+ }
}
@@ -2744,25 +2751,28 @@ static void mpx_read_fmap(MPX mpx, char *dbase) {
while ((buf = mpx_getline(mpx,fin)) != NULL) {
if (mpx->nfonts == (max_fnums+1))
mpx_abort(mpx,"Need to increase max_fnums");
- nam = buf;
- while (*buf && *buf != '\t')
- buf++;
+ nam = buf;
+ while (*buf && *buf != '\t')
+ buf++;
+ if (nam==buf)
+ continue;
tmp = xmalloc(sizeof(avl_entry),1);
- tmp->name = nam;
+ tmp->name = xmalloc (1,(buf-nam)+1);
+ strncpy(tmp->name,nam,(buf-nam));
+ tmp->name[(buf-nam)] = '\0';
tmp->num = (int)mpx->nfonts++;
- (void)mpx_avl_probe (mpx,mpx->trfonts, tmp) ;
+ assert(avl_ins (tmp, mpx->trfonts, avl_false) > 0);
if (*buf) {
- *buf = 0; buf++;
- do buf++; while (*buf == '\t');
- while (*buf && *buf != '\t'); buf++; /* skip over psname */
- do buf++; while (*buf == '\t');
+ buf++;
+ while (*buf == '\t') buf++;
+ while (*buf && *buf != '\t') buf++; /* skip over psname */
+ while (*buf == '\t') buf++;
if (*buf)
nam = buf;
- while (*buf); buf++;
+ while (*buf) buf++;
}
mpx->font_name[tmp->num] = xstrdup(nam);
mpx->font_num[tmp->num] = -1; /* indicate font is not mounted */
- mpx->nfonts++;
}
mpx_fclose(mpx,fin);
}
@@ -2919,8 +2929,11 @@ static int mpx_scan_desc_line(MPX mpx, int f, char *lin) {
t = lin;
while (*lin != ' ' && *lin != '\t' && *lin != '\0')
lin++;
+ if (lin==t)
+ return 1;
s = xmalloc((size_t)(lin-t+1),1);
strncpy(s,t,(size_t)(lin-t));
+ *(s+(lin-t)) = '\0';
while (*lin == ' ' || *lin == '\t')
lin++;
if (*lin == '"') {
@@ -2928,7 +2941,7 @@ static int mpx_scan_desc_line(MPX mpx, int f, char *lin) {
tmp = xmalloc(sizeof(avl_entry),1);
tmp->name = s ;
tmp->num = lastcode;
- (void)mpx_avl_probe (mpx, mpx->charcodes[f],tmp);
+ mpx_avl_probe (mpx, mpx->charcodes[f],tmp);
}
} else {
(void) mpx_get_float_map(mpx,lin);
@@ -2940,7 +2953,7 @@ static int mpx_scan_desc_line(MPX mpx, int f, char *lin) {
tmp = xmalloc(sizeof(avl_entry),1);
tmp->name = s ;
tmp->num = lastcode;
- (void)mpx_avl_probe (mpx, mpx->charcodes[f],tmp);
+ mpx_avl_probe (mpx, mpx->charcodes[f],tmp);
}
}
return 1;
@@ -3002,6 +3015,7 @@ static void mpx_slant_and_ht(MPX mpx);
@ @c
static void mpx_slant_and_ht(MPX mpx) {
int i = 0;
+ fprintf(mpx->mpxfile, "(");
if (mpx->Xslant != 0.0) {
fprintf(mpx->mpxfile, " slanted%.5f", mpx->Xslant);
i++;
@@ -3010,8 +3024,7 @@ static void mpx_slant_and_ht(MPX mpx) {
fprintf(mpx->mpxfile, " yscaled%.4f", mpx->Xheight / mpx->cursize);
i++;
}
- if (i > 0)
- fprintf(mpx->mpxfile, "\n ");
+ fprintf(mpx->mpxfile, ")");
}
@@ -3024,7 +3037,7 @@ static void mpx_set_num_char(MPX mpx, int f, int c) {
hh = (float)mpx->h;
vv = (float)mpx->v;
- for (i = mpx->shiftbase[f]; mpx->shiftchar[i] >= 0; i++)
+ for (i = mpx->shiftbase[f]; mpx->shiftchar[i] >= 0 && i < SHIFTS; i++)
if (mpx->shiftchar[i] == c) {
hh += (mpx->cursize / mpx->unit) * mpx->shifth[i];
vv += (mpx->cursize / mpx->unit) * mpx->shiftv[i];
@@ -3184,17 +3197,22 @@ OUT_LABEL:
sp = xmalloc(sizeof(spec_entry),1);
sp->name = cname;
sp->mac = NULL;
- sp = (spec_entry *)avl_probe(mpx->spec_tab,sp);
- if (sp==NULL)
- mpx_abort(mpx,"Memory allocation failure");
+ {
+ spec_entry *r = (spec_entry *)avl_find(sp, mpx->spec_tab);
+ if (r==NULL) {
+ if (avl_ins (sp, mpx->spec_tab, avl_false)<0)
+ mpx_abort(mpx,"Memory allocation failure");
+ }
+ }
if (sp->mac == NULL) {
sp->mac = mpx_copy_spec_char(mpx, cname); /* this won't be NULL */
}
- fprintf(mpx->mpxfile, "_s(%s(n%d)", sp->mac, mpx->font_num[f]);
- mpx_slant_and_ht(mpx);
- fprintf(mpx->mpxfile, ",%.5f,%.4f,%.4f);\n",
+ fprintf(mpx->mpxfile, "_s(%s(_n%d)", sp->mac,f);
+ fprintf(mpx->mpxfile, ",%.5f,%.4f,%.4f)",
(mpx->cursize/mpx->font_design_size[f])*1.00375,
- (double)(mpx->h*mpx->unit), YCORR-mpx->v*mpx->unit);
+ (double)((mpx->h*mpx->unit)/100.0), YCORR-mpx->v*mpx->unit);
+ mpx_slant_and_ht(mpx);
+ fprintf(mpx->mpxfile, ";\n");
}
}
@@ -3213,7 +3231,7 @@ static void mpx_do_font_def(MPX mpx, int n, char *nam) {
if (p==NULL)
mpx_abort(mpx, "Font %s was not in map file", nam);
f = p->num;
- if ( mpx->info_base[f]==max_widths ) {
+ if ( mpx->charcodes[f] == NULL) {
mpx_read_fontdesc(mpx, nam);
mpx->cur_name = xstrdup(mpx->font_name[f]);
if (! mpx_open_tfm_file(mpx) )
@@ -3699,13 +3717,13 @@ static int mpx_do_page (MPX mpx, FILE *trf) {
static int mpx_dmp(MPX mpx, char *infile) {
int more;
FILE *trf = mpx_xfopen(mpx,infile, "r");
- mpx_open_mpxfile(mpx);
- if (mpx->banner != NULL)
- fprintf (mpx->mpxfile,"%s\n",mpx->banner);
mpx_read_desc(mpx);
mpx_read_fmap(mpx,dbname);
if (!mpx->gflag)
mpx_read_char_adj(mpx,adjname);
+ mpx_open_mpxfile(mpx);
+ if (mpx->banner != NULL)
+ fprintf (mpx->mpxfile,"%s\n",mpx->banner);
if (mpx_do_page(mpx, trf)) {
do {
@<Do initialization required before starting a new page@>;
@@ -3716,7 +3734,6 @@ static int mpx_dmp(MPX mpx, char *infile) {
} while (more);
}
mpx_fclose(mpx,trf);
- mpx_fclose(mpx,mpx->mpxfile);
if ( mpx->history<=mpx_cksum_trouble )
return 0;
else
@@ -4245,6 +4262,7 @@ that to the command line.
/* split the command in bits */
cmdbitlength = split_pipes(mpx->maincmd, cmdbits);
+ cmdline = NULL;
for (i = 0; i < cmdbitlength; i++) {
if (cmdline!=NULL) free(cmdline);
@@ -4263,11 +4281,11 @@ that to the command line.
cur_in = tmp_b;
cur_out = tmp_a;
}
- strcpy(infile,cur_in);
}
}
- if (tmp_a!=infile) { remove(tmp_a); }
- if (tmp_b!=infile) { remove(tmp_b); }
+ if (tmp_a!=cur_out) { remove(tmp_a); }
+ if (tmp_b!=cur_out) { remove(tmp_b); }
+ strcpy(infile,cur_out);
}
@ If MPX file is up-to-date or if MP file does not exist, do nothing.
diff --git a/Build/source/texk/web2c/mplibdir/psout.w b/Build/source/texk/web2c/mplibdir/psout.w
index 90bc96a9aa3..87be9dc25e4 100644
--- a/Build/source/texk/web2c/mplibdir/psout.w
+++ b/Build/source/texk/web2c/mplibdir/psout.w
@@ -1,4 +1,4 @@
-% $Id: psout.w 878 2009-03-22 08:22:33Z taco $
+% $Id: psout.w 963 2009-04-21 13:35:03Z taco $
%
% Copyright 2008 Taco Hoekwater.
%
@@ -96,20 +96,6 @@ typedef struct psout_data_struct {
} psout_data_struct ;
@<Exported function headers@>
-@
-@c
-void *avl_probe (avl_tree t, void *p) {
- int ret = avl_ins(p, t, false);
- if (ret < 0)
- return NULL;
- else
- return avl_find(p, t);
-}
-
-@ @<Exported...@>=
-void *avl_probe (avl_tree t, void *p) ;
-
-
@ @c
static boolean mp_isdigit (int a) {
return (a>='0'&&a<='9');
@@ -144,6 +130,7 @@ void mp_ps_backend_free (MP mp) ;
@
@c void mp_ps_backend_initialize (MP mp) {
mp->ps = mp_xmalloc(mp,1,sizeof(psout_data_struct));
+ memset(mp->ps,0,sizeof(psout_data_struct));
@<Set initial values@>;
}
void mp_ps_backend_free (MP mp) {
@@ -209,6 +196,15 @@ static void mp_ps_print (MP mp, const char *ss) {
ps_room(strlen(ss));
mp_ps_do_print(mp, ss, strlen(ss));
}
+static void mp_ps_dsc_print (MP mp, const char *dsc, const char *ss) {
+ ps_room(strlen(ss));
+ if (mp->ps->ps_offset==0) {
+ mp_ps_do_print(mp, "%%+ ", 4);
+ mp_ps_do_print(mp, dsc, strlen(dsc));
+ mp_ps_print_char(mp, ' ');
+ }
+ mp_ps_do_print(mp, ss, strlen(ss));
+}
@ The procedure |print_nl| is like |print|, but it makes sure that the
string appears at the beginning of a new line.
@@ -416,7 +412,9 @@ static void mp_load_enc (MP mp, char *enc_name,
char *myname;
unsigned save_selector = mp->selector;
if (!mp_enc_open (mp,enc_name)) {
- mp_print (mp,"cannot open encoding file for reading");
+ char err [256];
+ mp_snprintf(err,255, "cannot open encoding file %s for reading", enc_name);
+ mp_print (mp,err);
return;
}
mp_normalize_selector(mp);
@@ -476,6 +474,7 @@ DONE:
static void mp_read_enc (MP mp, enc_entry * e) {
if (e->loaded)
return;
+ mp_xfree(e->enc_name);
e->enc_name = NULL;
mp_load_enc (mp,e->file_name, &e->enc_name, e->glyph_names);
e->loaded = true;
@@ -548,15 +547,20 @@ static void *destroy_enc_entry (void *pa) {
for (i = 0; i < 256; i++)
if (p->glyph_names[i] != notdef)
mp_xfree (p->glyph_names[i]);
+ mp_xfree (p->enc_name);
mp_xfree (p->glyph_names);
mp_xfree (p);
+ return NULL;
}
static void *copy_enc_entry (const void *pa) {
enc_entry *p, *q;
int i;
p = (enc_entry *) pa;
q = malloc (sizeof (enc_entry));
+ memset(q,0,sizeof(enc_entry));
if (q!=NULL) {
+ if (p->enc_name!=NULL)
+ q->enc_name = strdup (p->enc_name);
q->loaded = p->loaded;
q->file_name = strdup (p->file_name);
q->objnum = p->objnum;
@@ -565,10 +569,10 @@ static void *copy_enc_entry (const void *pa) {
if (p->glyph_names == NULL)
return NULL;
for (i = 0; i < 256; i++) {
- if (p->glyph_names[i]!=NULL)
+ if (p->glyph_names[i]!=notdef)
q->glyph_names[i] = strdup(p->glyph_names[i]);
else
- q->glyph_names[i] = NULL;
+ q->glyph_names[i] = (char *)notdef;
}
}
return (void *)q;
@@ -577,7 +581,7 @@ static void *copy_enc_entry (const void *pa) {
static enc_entry * mp_add_enc (MP mp, char *s) {
int i;
enc_entry tmp, *p;
- void **aa;
+
if (mp->ps->enc_tree == NULL) {
mp->ps->enc_tree = avl_create (comp_enc_entry,
copy_enc_entry,
@@ -589,6 +593,7 @@ static enc_entry * mp_add_enc (MP mp, char *s) {
if (p != NULL) /* encoding already registered */
return p;
p = mp_xmalloc (mp,1,sizeof (enc_entry));
+ memset(p,0,sizeof(enc_entry));
p->loaded = false;
p->file_name = mp_xstrdup (mp,s);
p->objnum = 0;
@@ -596,8 +601,9 @@ static enc_entry * mp_add_enc (MP mp, char *s) {
p->glyph_names = mp_xmalloc (mp,256,sizeof (char *));
for (i = 0; i < 256; i++)
p->glyph_names[i] = (char *) notdef;
- aa = avl_probe (mp->ps->enc_tree, p);
- return p;
+ assert (avl_ins (p, mp->ps->enc_tree, avl_false)>0);
+ destroy_enc_entry(p);
+ return avl_find (&tmp, mp->ps->enc_tree);
}
@ cleaning up...
@@ -775,6 +781,7 @@ static void * delete_fm_entry (void *p) {
mp_xfree (fm->subset_tag);
mp_xfree (fm->charset);
mp_xfree (fm);
+ return NULL;
}
static ff_entry *new_ff_entry (MP mp) {
@@ -801,6 +808,7 @@ static void * delete_ff_entry (void *p) {
mp_xfree (ff->ff_name);
mp_xfree (ff->ff_path);
mp_xfree (ff);
+ return NULL;
}
static char *mk_base_tfm (MP mp, char *tfmname, int *i) {
@@ -908,18 +916,13 @@ with the original version.
@d LINK_PS 0x02
@d set_tfmlink(fm) ((fm)->links |= LINK_TFM)
@d set_pslink(fm) ((fm)->links |= LINK_PS)
-@d unset_tfmlink(fm) ((fm)->links &= ~LINK_TFM)
-@d unset_pslink(fm) ((fm)->links &= ~LINK_PS)
@d has_tfmlink(fm) ((fm)->links & LINK_TFM)
@d has_pslink(fm) ((fm)->links & LINK_PS)
@c
static int avl_do_entry (MP mp, fm_entry * fp, int mode) {
fm_entry *p;
- void *a;
- void **aa;
char s[128];
-
/* handle |tfm_name| link */
if (strcmp (fp->tfm_name, nontfm)) {
@@ -938,16 +941,14 @@ static int avl_do_entry (MP mp, fm_entry * fp, int mode) {
mp_warn(mp,s);
goto exit;
}
- (void) avl_del (p,mp->ps->tfm_tree,&a);
- assert (a != NULL);
- unset_tfmlink (p);
- if (!has_pslink (p))
- delete_fm_entry (p);
+ (void) avl_del (p,mp->ps->tfm_tree,NULL);
+ p = NULL;
}
}
if (mode != FM_DELETE) {
- aa = avl_probe (mp->ps->tfm_tree, fp);
- assert (aa != NULL);
+ if (p==NULL) {
+ assert (avl_ins(fp, mp->ps->tfm_tree, avl_false)>0);
+ }
set_tfmlink (fp);
}
}
@@ -973,16 +974,14 @@ static int avl_do_entry (MP mp, fm_entry * fp, int mode) {
mp_warn(mp,s);
goto exit;
}
- (void)avl_del (p,mp->ps->ps_tree,&a);
- assert (a != NULL);
- unset_pslink (p);
- if (!has_tfmlink (p))
- delete_fm_entry (p);
+ (void)avl_del (p,mp->ps->ps_tree,NULL);
+ p= NULL;
}
}
if (mode != FM_DELETE) {
- aa = avl_probe (mp->ps->ps_tree, fp);
- assert (aa != NULL);
+ if (p==NULL) {
+ assert (avl_ins(fp, mp->ps->ps_tree, avl_false)>0);
+ }
set_pslink (fp);
}
}
@@ -1244,10 +1243,10 @@ static int check_fm_entry (MP mp, fm_entry * fm, boolean warn) {
* no embedding: 'cmr10.pfa'
*/
if (a == '<' || u == '<') {
- set_included (fm);
- if ((a == '<' && b == 0) || (a == 0 && v == 0))
- set_subsetted (fm);
- /* otherwise b == '<' (or '[') => no subsetting */
+ set_included (fm);
+ if ((a == '<' && b == 0) || (a == 0 && v == 0))
+ set_subsetted (fm);
+ /* otherwise b == '<' (or '[') => no subsetting */
}
set_field (ff_name);
u = v = 0;
@@ -1270,8 +1269,10 @@ static int check_fm_entry (MP mp, fm_entry * fm, boolean warn) {
fm points to a valid, freshly filled-out |fm_entry| structure.
Now follows the actual work of registering/deleting.
*/
- if (avl_do_entry (mp, fm, mp->ps->mitem->mode) == 0) /* if success */
+ if (avl_do_entry (mp, fm, mp->ps->mitem->mode) == 0) { /* if success */
+ delete_fm_entry (fm);
return;
+ }
bad_line:
delete_fm_entry (fm);
}
@@ -1371,7 +1372,6 @@ fm_entry * mp_fm_lookup (MP mp, font_number f) {
static ff_entry *check_ff_exist (MP mp, fm_entry * fm) {
ff_entry *ff;
ff_entry tmp;
- void **aa;
assert (fm->ff_name != NULL);
tmp.ff_name = fm->ff_name;
@@ -1380,8 +1380,9 @@ static ff_entry *check_ff_exist (MP mp, fm_entry * fm) {
ff = new_ff_entry (mp);
ff->ff_name = mp_xstrdup (mp,fm->ff_name);
ff->ff_path = mp_xstrdup (mp,fm->ff_name);
- aa = avl_probe (mp->ps->ff_tree, ff);
- assert (aa != NULL);
+ assert(avl_ins (ff, mp->ps->ff_tree, avl_false)>0);
+ delete_ff_entry(ff);
+ ff = (ff_entry *) avl_find (&tmp, mp->ps->ff_tree);
}
return ff;
}
@@ -1445,12 +1446,17 @@ void mp_init_map_file (MP mp, int is_troff);
@ @c
void mp_map_file (MP mp, str_number t) {
- char *s = mp_xstrdup(mp,mp_str (mp,t));
+ char *ss = mp_str (mp,t);
+ char *s = mp_xstrdup(mp, ss);
mp_process_map_item (mp, s, MAPFILE);
+ mp_xfree(ss);
}
void mp_map_line (MP mp, str_number t) {
- char *s = mp_xstrdup(mp,mp_str (mp,t));
+ char *ss = mp_str (mp,t);
+ char *s = mp_xstrdup(mp,ss);
mp_process_map_item (mp, s, MAPLINE);
+ mp_xfree(ss);
+ mp_xfree(s);
}
@
@@ -1479,34 +1485,6 @@ if (mp->ps->mitem!=NULL) {
mp_xfree(mp->ps->mitem);
}
-@ cleaning up...
-
-@c
-static void destroy_fm_entry_tfm (void *pa, void *pb) {
- fm_entry *fm;
- (void)pb;
- fm = (fm_entry *) pa;
- if (!has_pslink (fm))
- delete_fm_entry (fm);
- else
- unset_tfmlink (fm);
-}
-static void destroy_fm_entry_ps (void *pa, void *pb) {
- fm_entry *fm;
- (void)pb;
- fm = (fm_entry *) pa;
- if (!has_tfmlink (fm))
- delete_fm_entry (fm);
- else
- unset_pslink (fm);
-}
-static void destroy_ff_entry (void *pa, void *pb) {
- ff_entry *ff;
- (void)pb;
- ff = (ff_entry *) pa;
- delete_ff_entry (ff);
-}
-
@ @<Declarations@>=
static void fm_free (MP mp);
@@ -1535,16 +1513,19 @@ void mp_read_psname_table (MP mp) ;
@ @c
void mp_read_psname_table (MP mp) {
font_number k;
+ char *s;
if (mp->ps->mitem == NULL) {
mp->ps->mitem = mp_xmalloc (mp,1,sizeof(mapitem));
mp->ps->mitem->mode = FM_DUPIGNORE;
mp->ps->mitem->type = MAPFILE;
mp->ps->mitem->map_line = NULL;
}
- mp->ps->mitem->map_line = mp_xstrdup (mp,ps_tab_name);
+ s = mp_xstrdup (mp,ps_tab_name);
+ mp->ps->mitem->map_line = s;
fm_read_info (mp);
for (k=mp->last_ps_fnum+1;k<=mp->last_fnum;k++) {
if (mp_has_fm_entry(mp, k, NULL)) {
+ mp_xfree(mp->font_ps_name[k]);
mp->font_ps_name[k] = mp_fm_font_name(mp,k);
}
}
@@ -1690,6 +1671,7 @@ static void make_subset_tag (MP mp, fm_entry * fm_cur, char **glyph_names, font_
crc /= 26;
}
tag[6] = 0;
+ mp_xfree(fm_cur->subset_tag);
fm_cur->subset_tag = mp_xstrdup (mp,tag);
}
@@ -2364,12 +2346,15 @@ static void t1_builtin_enc (MP mp) {
if (t1_suffix ("def")) { /* predefined encoding */
(void)sscanf (mp->ps->t1_line_array + strlen ("/Encoding"), "%256s", mp->ps->t1_buf_array);
if (strcmp (mp->ps->t1_buf_array, "StandardEncoding") == 0) {
- for (i = 0; i < 256; i++)
+ for (i = 0; i < 256; i++) {
+ if (mp->ps->t1_builtin_glyph_names[i] != notdef)
+ mp_xfree(mp->ps->t1_builtin_glyph_names[i]);
if (standard_glyph_names[i] == notdef)
mp->ps->t1_builtin_glyph_names[i] = (char *) notdef;
else
mp->ps->t1_builtin_glyph_names[i] =
mp_xstrdup (mp,standard_glyph_names[i]);
+ }
mp->ps->t1_encoding = ENC_STANDARD;
} else {
char s[128];
@@ -2396,8 +2381,12 @@ static void t1_builtin_enc (MP mp) {
* ...
* readonly def
*/
- for (i = 0; i < 256; i++)
- mp->ps->t1_builtin_glyph_names[i] = (char *) notdef;
+ for (i = 0; i < 256; i++) {
+ if (mp->ps->t1_builtin_glyph_names[i] != notdef) {
+ mp_xfree(mp->ps->t1_builtin_glyph_names[i]);
+ mp->ps->t1_builtin_glyph_names[i] = (char *) notdef;
+ }
+ }
if (t1_prefix ("/Encoding [") || t1_prefix ("/Encoding[")) { /* the first case */
r = strchr (mp->ps->t1_line_array, '[') + 1;
skip (r, ' ');
@@ -2412,8 +2401,11 @@ static void t1_builtin_enc (MP mp) {
mp_fatal_error
(mp, "encoding vector contains more than 256 names");
}
- if (strcmp (mp->ps->t1_buf_array, notdef) != 0)
- mp->ps->t1_builtin_glyph_names[counter] = mp_xstrdup (mp,mp->ps->t1_buf_array);
+ if (strcmp (mp->ps->t1_buf_array, notdef) != 0) {
+ if (mp->ps->t1_builtin_glyph_names[counter] != notdef)
+ mp_xfree(mp->ps->t1_builtin_glyph_names[counter]);
+ mp->ps->t1_builtin_glyph_names[counter] = mp_xstrdup (mp,mp->ps->t1_buf_array);
+ }
counter++;
}
if (*r != 10 && *r != '%') {
@@ -2443,9 +2435,12 @@ static void t1_builtin_enc (MP mp) {
*/
if (sscanf (p, "dup %i%256s put", &i, mp->ps->t1_buf_array) == 2 &&
*mp->ps->t1_buf_array == '/' && valid_code (i)) {
- if (strcmp (mp->ps->t1_buf_array + 1, notdef) != 0)
+ if (strcmp (mp->ps->t1_buf_array + 1, notdef) != 0) {
+ if (mp->ps->t1_builtin_glyph_names[i] != notdef)
+ mp_xfree(mp->ps->t1_builtin_glyph_names[i]);
mp->ps->t1_builtin_glyph_names[i] =
mp_xstrdup (mp,mp->ps->t1_buf_array + 1);
+ }
p = strstr (p, " put") + strlen (" put");
skip (p, ' ');
}
@@ -2496,6 +2491,13 @@ static void t1_check_end (MP mp) {
t1_putline (mp);
}
+@ @<Set initial values...@>=
+{
+ int i;
+ for (i = 0; i < 256; i++)
+ mp->ps->t1_builtin_glyph_names[i] = (char *) notdef;
+}
+
@ @<Types...@>=
typedef struct {
char *ff_name; /* base name of font file */
@@ -2511,7 +2513,9 @@ static boolean t1_open_fontfile (MP mp, fm_entry *fm_cur,const char *open_name_p
mp->ps->t1_file = (mp->open_file)(mp,ff->ff_path, "r", mp_filetype_font);
}
if (mp->ps->t1_file == NULL) {
- mp_warn (mp, "cannot open Type 1 font file for reading");
+ char err [256];
+ mp_snprintf(err, 255, "cannot open Type 1 font file %s for reading", ff->ff_path);
+ mp_warn (mp,err);
return false;
}
t1_init_params (mp,open_name_prefix,fm_cur->ff_name);
@@ -3092,6 +3096,15 @@ static void t1_flush_cs (MP mp, boolean is_subr)
mp_xfree (tab);
mp_xfree (start_line);
mp_xfree (line_end);
+ if (is_subr) {
+ mp->ps->subr_array_start = NULL;
+ mp->ps->subr_array_end = NULL;
+ mp->ps->subr_tab = NULL;
+ } else {
+ mp->ps->cs_dict_start = NULL;
+ mp->ps->cs_dict_end = NULL;
+ mp->ps->cs_tab = NULL;
+ }
}
static void t1_mark_glyphs (MP mp, font_number tex_font)
@@ -3221,6 +3234,7 @@ static int t1_updatefm (MP mp, font_number f, fm_entry *fm)
while (*p != ' ' && *p != 0)
p++;
*p=0;
+ mp_xfree(fm->ps_name);
fm->ps_name = s;
t1_close_font_file (mp,"");
return 1;
@@ -3264,8 +3278,30 @@ static void t1_free (MP mp);
@ @c
static void t1_free (MP mp) {
+ int k;
+
+ mp_xfree (mp->ps->subr_array_start);
+ mp_xfree (mp->ps->subr_array_end);
+ mp_xfree (mp->ps->cs_dict_start);
+ mp_xfree (mp->ps->cs_dict_end);
+ cs_init(mp);
+
mp_xfree (mp->ps->t1_line_array);
+ mp_xfree (mp->ps->char_array);
+ mp->ps->char_array=NULL;
+
+ mp->ps->t1_line_array = mp->ps->t1_line_ptr = NULL;
+ mp->ps->t1_line_limit = 0;
mp_xfree (mp->ps->t1_buf_array);
+ mp->ps->t1_buf_array = mp->ps->t1_buf_ptr = NULL;
+ mp->ps->t1_buf_limit = 0;
+
+ for (k=0;k<=255;k++) {
+ if (mp->ps->t1_builtin_glyph_names[k] != notdef) {
+ mp_xfree(mp->ps->t1_builtin_glyph_names[k]);
+ mp->ps->t1_builtin_glyph_names[k] = (char *)notdef;
+ }
+ }
}
@* Embedding Charstrings.
@@ -3280,6 +3316,7 @@ typedef struct mp_ps_font {
cs_entry *cs_tab;
cs_entry *cs_ptr;
cs_entry *subr_tab;
+ int subr_size;
int t1_lenIV;
int slant;
int extend;
@@ -3350,6 +3387,8 @@ mp_ps_font *mp_ps_font_parse (MP mp, int tex_font) {
mp->ps->cs_ptr = NULL;
f->subr_tab = mp->ps->subr_tab;
mp->ps->subr_tab = NULL;
+ f->subr_size = mp->ps->subr_size;
+ mp->ps->subr_size = mp->ps->subr_size_pos = 0;
f->t1_lenIV = mp->ps->t1_lenIV;
t1_close_font_file (mp,">");
return f;
@@ -3362,7 +3401,22 @@ mp_ps_font *mp_ps_font_parse (MP mp, int tex_font);
@c
void mp_ps_font_free (MP mp, mp_ps_font *f) {
- (void)mp;
+ cs_entry *ptr;
+ for (ptr = f->cs_tab; ptr < f->cs_ptr; ptr++) {
+ if (ptr->glyph_name != notdef)
+ mp_xfree (ptr->glyph_name);
+ mp_xfree(ptr->data);
+ }
+ mp_xfree(f->cs_tab);
+ f->cs_tab = NULL;
+ for (ptr = f->subr_tab; ptr - f->subr_tab < f->subr_size; ptr++) {
+ if (ptr->glyph_name != notdef)
+ mp_xfree (ptr->glyph_name);
+ mp_xfree(ptr->data);
+ }
+ mp_xfree(f->subr_tab);
+ f->subr_tab = NULL;
+ t1_free(mp);
mp_xfree(f);
}
@@ -3381,14 +3435,21 @@ mp_knot *pp; /* the last known knot in the subpath */
@ @c
-mp_edge_object *mp_ps_font_charstring (MP mp, mp_ps_font *f, int c) {
+mp_edge_object *mp_ps_do_font_charstring (MP mp, mp_ps_font *f, char *nam) {
mp_edge_object *h = NULL;
f->h = NULL; f->p = NULL; f->pp = NULL; /* just in case */
f->cur_x = f->cur_y = 0.0;
f->orig_x = f->orig_y = 0.0;
- if (cs_parse(mp,f,f->t1_glyph_names[c], 0)) {
+ if (nam==NULL) {
+ mp_warn(mp,"nonexistant glyph requested");
+ return h;
+ }
+ if (cs_parse(mp,f,nam, 0)) {
h = f->h;
} else {
+ char err[256];
+ mp_snprintf(err,255,"Glyph interpreter failed (missing glyph '%s'?)", nam);
+ mp_warn(mp,err);
if (f->h != NULL) {
finish_subpath();
mp_gr_toss_objects(f->h);
@@ -3398,10 +3459,18 @@ mp_edge_object *mp_ps_font_charstring (MP mp, mp_ps_font *f, int c) {
return h;
}
+mp_edge_object *mp_ps_font_charstring (MP mp, mp_ps_font *f, int c) {
+ char *s = NULL;
+ if (f != NULL && f->t1_glyph_names != NULL && c>=0 && c<256)
+ s = f->t1_glyph_names[c];
+ return mp_ps_do_font_charstring(mp,f,s);
+}
+
@ @<Exported function headers@>=
mp_edge_object *mp_ps_font_charstring (MP mp, mp_ps_font *f, int c);
+mp_edge_object *mp_ps_do_font_charstring (MP mp, mp_ps_font *f, char *n);
@
@@ -3416,8 +3485,8 @@ boolean cs_parse (MP mp, mp_ps_font *f, const char *cs_name, int subr);
assert(f->pp == NULL);
assert(f->p == NULL);
f->pp = mp_xmalloc(mp, 1, sizeof (mp_knot));
- f->pp->left_type = mp_endpoint;
- f->pp->right_type = mp_open;
+ f->pp->left_type = mp_explicit;
+ f->pp->right_type = mp_explicit;
f->pp->x_coord = scaled_from_double(f->cur_x + dx);
f->pp->y_coord = scaled_from_double(f->cur_y + dy);
f->pp->left_x = f->pp->right_x = f->pp->x_coord;
@@ -3447,8 +3516,8 @@ boolean cs_parse (MP mp, mp_ps_font *f, const char *cs_name, int subr);
@d add_line_segment(f,dx,dy) do {
assert(f->pp != NULL);
n = mp_xmalloc(mp,1, sizeof (mp_knot));
- n->left_type = mp_open;
- n->right_type = mp_endpoint;
+ n->left_type = mp_explicit;
+ n->right_type = mp_explicit;
n->next = gr_path_p((mp_fill_object *)f->p); /* loop */
n->x_coord = scaled_from_double(f->cur_x + dx);
n->y_coord = scaled_from_double(f->cur_y + dy);
@@ -3456,7 +3525,6 @@ boolean cs_parse (MP mp, mp_ps_font *f, const char *cs_name, int subr);
n->right_y = n->y_coord;
n->left_x = n->x_coord;
n->left_y = n->y_coord;
- f->pp->right_type = mp_open;
f->pp->next = n;
f->pp = n;
f->cur_x += dx;
@@ -3465,8 +3533,8 @@ boolean cs_parse (MP mp, mp_ps_font *f, const char *cs_name, int subr);
@d add_curve_segment(f,dx1,dy1,dx2,dy2,dx3,dy3) do {
n = mp_xmalloc(mp, 1, sizeof (mp_knot));
- n->left_type = mp_open;
- n->right_type = mp_endpoint;
+ n->left_type = mp_explicit;
+ n->right_type = mp_explicit;
n->next = gr_path_p((mp_fill_object *)f->p); /* loop */
n->x_coord = scaled_from_double(f->cur_x + dx1 + dx2 + dx3);
n->y_coord = scaled_from_double(f->cur_y + dy1 + dy2 + dy3);
@@ -3476,7 +3544,6 @@ boolean cs_parse (MP mp, mp_ps_font *f, const char *cs_name, int subr);
n->left_y = scaled_from_double(f->cur_y + dy1 + dy2);
f->pp->right_x = scaled_from_double(f->cur_x + dx1);
f->pp->right_y = scaled_from_double(f->cur_y + dy1);
- f->pp->right_type = mp_open;
f->pp->next = n;
f->pp = n;
f->cur_x += dx1 + dx2 + dx3;
@@ -3521,7 +3588,8 @@ boolean cs_parse (MP mp, mp_ps_font *f, const char *cs_name, int subr)
}
ptr = f->cs_tab+i; /* this is the right charstring */
}
-
+ if (ptr==f->cs_ptr)
+ return false;
data = ptr->data + 4;
cr = 4330;
cs_len = (int)ptr->cslen;
@@ -3875,14 +3943,14 @@ char * mp_fm_font_name (MP mp, font_number f) {
if (mp_has_fm_entry (mp, f,&fm)) {
if (fm != NULL && (fm->ps_name != NULL)) {
if (mp_font_is_included(mp, f) && !mp->font_ps_name_fixed[f]) {
- /* find the real fontname, and update |ps_name| and |subset_tag| if needed */
+ /* find the real fontname, and update |ps_name| and |subset_tag| if needed */
if (t1_updatefm(mp,f,fm)) {
- mp->font_ps_name_fixed[f] = true;
- } else {
- print_err ("font loading problems for font ");
+ mp->font_ps_name_fixed[f] = true;
+ } else {
+ print_err ("font loading problems for font ");
mp_print(mp,mp->font_name[f]);
mp_error(mp);
- }
+ }
}
return mp_xstrdup(mp,fm->ps_name);
}
@@ -3997,7 +4065,7 @@ static void mp_list_used_resources (MP mp, int prologues, int procset);
mp_ps_print_nl(mp, "%%+ encoding");
}
mp_ps_print_char(mp, ' ');
- mp_ps_print(mp, mp->font_enc_name[f]);
+ mp_ps_dsc_print(mp, "encoding", mp->font_enc_name[f]);
ldf=(int)f;
}
FOUND:
@@ -4020,11 +4088,13 @@ static void mp_list_used_resources (MP mp, int prologues, int procset);
mp_ps_print_nl(mp, "%%+ font");
}
mp_ps_print_char(mp, ' ');
- if ( (prologues==3)&&
- (mp_font_is_subsetted(mp,f)) )
- mp_ps_print(mp, mp_fm_font_subset_name(mp,f));
- else
- mp_ps_print(mp, mp->font_ps_name[f]);
+ if ( (prologues==3)&& (mp_font_is_subsetted(mp,f)) ) {
+ char *s = mp_fm_font_subset_name(mp,f);
+ mp_ps_dsc_print(mp, "font", s);
+ mp_xfree(s);
+ } else {
+ mp_ps_dsc_print(mp, "font", mp->font_ps_name[f]);
+ }
ldf=(int)f;
}
FOUND2:
@@ -4063,7 +4133,7 @@ static void mp_list_supplied_resources (MP mp, int prologues, int procset);
mp_ps_print_nl(mp, "%%+ encoding");
}
mp_ps_print_char(mp, ' ');
- mp_ps_print(mp, mp->font_enc_name[f]);
+ mp_ps_dsc_print(mp, "encoding", mp->font_enc_name[f]);
ldf=(int)f;
}
FOUND:
@@ -4088,10 +4158,13 @@ static void mp_list_supplied_resources (MP mp, int prologues, int procset);
mp_ps_print_nl(mp, "%%+ font");
}
mp_ps_print_char(mp, ' ');
- if ( mp_font_is_subsetted(mp,f) )
- mp_ps_print(mp, mp_fm_font_subset_name(mp,f));
- else
- mp_ps_print(mp, mp->font_ps_name[f]);
+ if ( mp_font_is_subsetted(mp,f) ) {
+ char *s = mp_fm_font_subset_name(mp,f);
+ mp_ps_dsc_print(mp, "font", s);
+ mp_xfree(s);
+ } else {
+ mp_ps_dsc_print(mp, "font", mp->font_ps_name[f]);
+ }
ldf=(int)f;
}
FOUND2:
@@ -4127,7 +4200,7 @@ static void mp_list_needed_resources (MP mp, int prologues);
mp_ps_print_nl(mp, "%%DocumentNeededResources: font");
}
mp_ps_print_char(mp, ' ');
- mp_ps_print(mp, mp->font_ps_name[f]);
+ mp_ps_dsc_print(mp, "font", mp->font_ps_name[f]);
ldf=(int)f;
}
FOUND:
@@ -4171,10 +4244,13 @@ static void mp_write_font_definition (MP mp, font_number f, int prologues);
(mp_xstrcmp(mp->font_name[f],"psyrgo")==0)||
(mp_xstrcmp(mp->font_name[f],"zpzdr-reversed")==0) ) {
if ( (mp_font_is_subsetted(mp,f))&&
- (mp_font_is_included(mp,f))&&(prologues==3))
- mp_ps_name_out(mp, mp_fm_font_subset_name(mp,f),true);
- else
+ (mp_font_is_included(mp,f))&&(prologues==3)) {
+ char *s = mp_fm_font_subset_name(mp,f);
+ mp_ps_name_out(mp, s,true);
+ mp_xfree(s);
+ } else {
mp_ps_name_out(mp, mp->font_ps_name[f],true);
+ }
mp_ps_print(mp, " fcp");
mp_ps_print_ln(mp);
if ( applied_reencoding(f) ) {
@@ -4216,10 +4292,13 @@ static void mp_ps_print_defined_name (MP mp, font_number f, int prologues);
@c static void mp_ps_print_defined_name(MP mp, font_number f, int prologues) {
mp_ps_print(mp, " /");
if ((mp_font_is_subsetted(mp,f))&&
- (mp_font_is_included(mp,f))&&(prologues==3))
- mp_ps_print(mp, mp_fm_font_subset_name(mp,f));
- else
+ (mp_font_is_included(mp,f))&&(prologues==3)) {
+ char *s = mp_fm_font_subset_name(mp,f);
+ mp_ps_print(mp, s);
+ mp_xfree(s);
+ } else {
mp_ps_print(mp, mp->font_ps_name[f]);
+ }
if ( mp_xstrcmp(mp->font_name[f],"psyrgo")==0 )
mp_ps_print(mp, "-Slanted");
if ( mp_xstrcmp(mp->font_name[f],"zpzdr-reversed")==0 )
@@ -5913,6 +5992,7 @@ while ( p!=null ) {
if (mp_has_fm_entry(mp,f,NULL) ) {
if (mp->font_enc_name[f]==NULL )
mp->font_enc_name[f] = mp_fm_encoding_name(mp,f);
+ mp_xfree(mp->font_ps_name[f]);
mp->font_ps_name[f] = mp_fm_font_name(mp,f);
}
break;
diff --git a/Build/source/texk/web2c/mplibdir/svgout.w b/Build/source/texk/web2c/mplibdir/svgout.w
index 22072530ac0..b2da35a0ea4 100644
--- a/Build/source/texk/web2c/mplibdir/svgout.w
+++ b/Build/source/texk/web2c/mplibdir/svgout.w
@@ -434,7 +434,6 @@ static void mp_svg_print_initial_comment(MP mp,mp_edge_object *hh);
@ @c
void mp_svg_print_initial_comment(MP mp,mp_edge_object *hh) {
scaled t, tx, ty;
- mp_svg_print(mp, "<?xml version=\"1.0\"?>");
@<Print the MetaPost version and time @>;
mp_svg_open_starttag(mp,"svg");
mp_svg_attribute(mp,"version", "1.1");
@@ -738,7 +737,6 @@ static void mp_svg_path_trans_out (MP mp, mp_knot *h, mp_pen_info *pen) {
mp_svg_trans_pair_out(mp, pen,gr_x_coord(q),gr_y_coord(q));
} else if ( q!=h ){
append_char('L');
- mp_svg_print(mp, "L ");
mp_svg_trans_pair_out(mp, pen,gr_x_coord(q),gr_y_coord(q));
}
p=q;
@@ -1203,7 +1201,13 @@ int mp_svg_gr_ship_out (mp_edge_object *hh, int qprologues, int standalone) {
mp_open_output_file(mp);
if ( (qprologues>=1) && (mp->last_ps_fnum<mp->last_fnum) )
mp_read_psname_table(mp);
- mp_svg_print_initial_comment(mp, hh);
+ /* The next seems counterintuitive, but calls from |mp_svg_ship_out|
+ * set standalone to true, and because embedded use is likely, it is
+ * better not to output the XML declaration in that case.
+ */
+ if (!standalone)
+ mp_svg_print(mp, "<?xml version=\"1.0\"?>");
+ mp_svg_print_initial_comment(mp, hh);
if (qprologues == 3) {
mp_svg_print_glyph_defs(mp, hh);
}