summaryrefslogtreecommitdiff
path: root/Build/source/texk/web2c/mplibdir/mp.w
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/texk/web2c/mplibdir/mp.w')
-rw-r--r--Build/source/texk/web2c/mplibdir/mp.w353
1 files changed, 246 insertions, 107 deletions
diff --git a/Build/source/texk/web2c/mplibdir/mp.w b/Build/source/texk/web2c/mplibdir/mp.w
index 2c956ea5a83..d52ad37ce8b 100644
--- a/Build/source/texk/web2c/mplibdir/mp.w
+++ b/Build/source/texk/web2c/mplibdir/mp.w
@@ -139,7 +139,7 @@ typedef struct MP_instance {
@ @c
/*\#define DEBUGENVELOPE */
-#ifdef DEBUGENVELOPE
+#ifdef DEBUGENVELOPE
static int DEBUGENVELOPECOUNTER=0;
#define dbg_str(A) printf("\n--[==[%03d DEBUGENVELOPE ]==] %s", DEBUGENVELOPECOUNTER++, #A)
#define dbg_n(A) printf("\n--[==[%03d DEBUGENVELOPE ]==] ['%s']=%s, ", DEBUGENVELOPECOUNTER++, #A, number_tostring(A))
@@ -176,8 +176,8 @@ static int DEBUGENVELOPECOUNTER=0;
#include <png.h> /* for |PNG_LIBPNG_VER_STRING|, |png_libpng_ver| */
/*\#include <pixman.h>*/ /* for |PIXMAN_VERSION_STRING|, |pixman_version_string()| */
/*\#include <cairo.h>*/ /* for |CAIRO_VERSION_STRING|, |cairo_version_string()| */
-#include <gmp.h> /* for |gmp_version| */
-#include <mpfr.h> /* for |MPFR_VERSION_STRING|, |mpfr_get_version()| */
+/*\#include <gmp.h>*/ /* for |gmp_version| */
+/*\#include <mpfr.h>*/ /* for |MPFR_VERSION_STRING|, |mpfr_get_version()| */
#include "mplib.h"
#include "mplibps.h" /* external header */
/*\#include "mplibsvg.h" */ /* external header */
@@ -189,7 +189,7 @@ static int DEBUGENVELOPECOUNTER=0;
#include "mpmath.h" /* internal header */
#include "mpmathdouble.h" /* internal header */
#include "mpmathdecimal.h" /* internal header */
-#include "mpmathbinary.h" /* internal header */
+/*#include "mpmathbinary.h"*/ /* internal header */
#include "mpstrings.h" /* internal header */
/* BEGIN PATCH */
mp_number dx_ap; /* approximation of dx */
@@ -200,12 +200,19 @@ mp_number ueps_ap; /* epsilon for above approximations */
boolean is_dxdy, is_dxindyin;
/* END PATCH */
-@ We move the {\tt cairo} and {\tt pixman} libraries outside {\tt mp.w},
+@ We move the {\tt cairo} and {\tt pixman} libraries outside {\tt mp.w},
to minimize dependencies.
@c
extern const char *COMPILED_CAIRO_VERSION_STRING;
extern const char* cairo_version_string (void);
+extern const char *COMPILED_MPFR_VERSION_STRING;
+extern const char* mpfr_get_version (void);
+extern void * mp_initialize_binary_math (MP mp) ;
+extern int COMPILED__GNU_MP_VERSION;
+extern int COMPILED__GNU_MP_VERSION_MINOR;
+extern int COMPILED__GNU_MP_VERSION_PATCHLEVEL;
+extern const char * const COMPILED_gmp_version;
extern const char *COMPILED_PIXMAN_VERSION_STRING;
extern const char* pixman_version_string (void);
extern void mp_png_backend_initialize (MP mp);
@@ -2628,7 +2635,7 @@ void mp_new_randoms (MP mp) {
mp->j_random = 54;
}
-@ To consume a random fraction, the program below will say `|next_random|'.
+@ To consume a random fraction, the program below will say `|next_random|'.
Now each number system has its own implementation,
true to the original as much as possibile.
@@ -2657,7 +2664,7 @@ As said before, now each number system has its own implementation.
@c
/*Unused.
static void mp\_unif\_rand (MP mp, mp\_number *ret, mp\_number x\_orig) {
- mp\_number y; // trial value
+ mp\_number y; // trial value
mp\_number x, abs\_x;
mp\_number u;
new\_fraction (y);
@@ -2896,7 +2903,7 @@ void *do_alloc_node (MP mp, size_t size) {
@c
void mp_xfree (void *x) {
- if (x != NULL)
+ if (x != NULL)
free (x);
}
void *mp_xrealloc (MP mp, void *p, size_t nmem, size_t size) {
@@ -3235,8 +3242,7 @@ mp_random_seed, /* initialize random number generator (\&{randomseed}) */
mp_message_command, /* communicate to user (\&{message}, \&{errmessage}) */
mp_every_job_command, /* designate a starting token (\&{everyjob}) */
mp_delimiters, /* define a pair of delimiters (\&{delimiters}) */
-mp_special_command, /* output special info (\&{special})
- or font map info (\&{fontmapfile}, \&{fontmapline}) */
+mp_special_command, /* output special info (\&{special}) or font map info (\&{fontmapfile}, \&{fontmapline}) */
mp_write_command, /* write text to a file (\&{write}) */
mp_type_name, /* declare a type (\&{numeric}, \&{pair}, etc.) */
mp_left_delimiter, /* the left delimiter of a matching pair */
@@ -3275,15 +3281,13 @@ mp_left_bracket, /* the operator `\.[' */
mp_right_bracket, /* the operator `\.]' */
mp_right_brace, /* the operator `\.{\char`\}}' */
mp_with_option, /* option for filling (\&{withpen}, \&{withweight}, etc.) */
-mp_thing_to_add,
- /* variant of \&{addto} (\&{contour}, \&{doublepath}, \&{also}) */
+mp_thing_to_add, /* variant of \&{addto} (\&{contour}, \&{doublepath}, \&{also}) */
mp_of_token, /* the operator `\&{of}' */
mp_to_token, /* the operator `\&{to}' */
mp_step_token, /* the operator `\&{step}' */
mp_until_token, /* the operator `\&{until}' */
mp_within_token, /* the operator `\&{within}' */
-mp_lig_kern_token,
- /* the operators `\&{kern}' and `\.{=:}' and `\.{=:\char'174}', etc. */
+mp_lig_kern_token, /* the operators `\&{kern}' and `\.{=:}' and `\.{=:\char'174}', etc. */
mp_assignment, /* the operator `\.{:=}' */
mp_skip_to, /* the operation `\&{skipto}' */
mp_bchar_label, /* the operator `\.{\char'174\char'174:}' */
@@ -4046,6 +4050,7 @@ enum mp_given_internal {
mp_pausing, /* positive to display lines on the terminal before they are read */
mp_showstopping, /* positive to stop after each \&{show} command */
mp_fontmaking, /* positive if font metric output is to be produced */
+ mp_texscriptmode, /* controls spacing in texmode */
mp_linejoin, /* as in \ps: 0 for mitered, 1 for round, 2 for beveled */
mp_linecap, /* as in \ps: 0 for butt, 1 for round, 2 for square */
mp_miterlimit, /* controls miter length as in \ps */
@@ -4196,6 +4201,8 @@ mp_primitive (mp, "showstopping", mp_internal_quantity, mp_showstopping);
@:mp_showstopping_}{\&{showstopping} primitive@>;
mp_primitive (mp, "fontmaking", mp_internal_quantity, mp_fontmaking);
@:mp_fontmaking_}{\&{fontmaking} primitive@>;
+mp_primitive (mp, "texscriptmode", mp_internal_quantity, mp_texscriptmode);
+@:mp_texscriptmode_}{\&{texscriptmode} primitive@>;
mp_primitive (mp, "linejoin", mp_internal_quantity, mp_linejoin);
@:mp_linejoin_}{\&{linejoin} primitive@>;
mp_primitive (mp, "linecap", mp_internal_quantity, mp_linecap);
@@ -4214,8 +4221,7 @@ mp_primitive (mp, "mpprocset", mp_internal_quantity, mp_procset);
@:mp_procset_}{\&{mpprocset} primitive@>;
mp_primitive (mp, "troffmode", mp_internal_quantity, mp_gtroffmode);
@:troffmode_}{\&{troffmode} primitive@>;
-mp_primitive (mp, "defaultcolormodel", mp_internal_quantity,
- mp_default_color_model);
+mp_primitive (mp, "defaultcolormodel", mp_internal_quantity, mp_default_color_model);
@:mp_default_color_model_}{\&{defaultcolormodel} primitive@>;
mp_primitive (mp, "restoreclipcolor", mp_internal_quantity, mp_restore_clip_color);
@:mp_restore_clip_color_}{\&{restoreclipcolor} primitive@>;
@@ -4273,6 +4279,7 @@ set_internal_string (mp_output_format, mp_intern (mp, "eps"));
set_internal_string (mp_output_format_options, mp_intern (mp, ""));
set_internal_string (mp_number_system, mp_intern (mp, "scaled"));
set_internal_from_number (mp_number_precision, precision_default);
+set_internal_from_number (mp_texscriptmode, unity_t);
#if DEBUG
number_clone (internal_value (mp_tracing_titles), three_t);
number_clone (internal_value (mp_tracing_equations), three_t);
@@ -4320,6 +4327,7 @@ set_internal_name (mp_design_size, xstrdup ("designsize"));
set_internal_name (mp_pausing, xstrdup ("pausing"));
set_internal_name (mp_showstopping, xstrdup ("showstopping"));
set_internal_name (mp_fontmaking, xstrdup ("fontmaking"));
+set_internal_name (mp_texscriptmode, xstrdup ("texscriptmode"));
set_internal_name (mp_linejoin, xstrdup ("linejoin"));
set_internal_name (mp_linecap, xstrdup ("linecap"));
set_internal_name (mp_miterlimit, xstrdup ("miterlimit"));
@@ -4443,6 +4451,8 @@ class numbers in nonstandard extensions of \MP.
@d invalid_class 20 /* bad character in the input */
@d max_class 20 /* the largest class number */
+@d semicolon_class 6 /* the ; */
+
@<Glob...@>=
#define digit_class 0 /* the class number of \.{0123456789} */
int char_class[256]; /* the class numbers */
@@ -4843,10 +4853,26 @@ char *mp_get_string_value (MP mp, const char *s, size_t l) {
return NULL;
}
+mp_knot mp_get_path_value (MP mp, const char *s, size_t l) {
+ char *ss = mp_xstrdup(mp,s);
+ if (ss) {
+ mp_sym sym = mp_id_lookup(mp,ss,l,false);
+ if (sym != NULL) {
+ if (mp_type(sym->v.data.node) == mp_path_type) {
+ mp_xfree (ss);
+ return (mp_knot) sym->v.data.node->data.p;
+ }
+ }
+ }
+ mp_xfree (ss);
+ return NULL;
+}
+
@ @<Exported function headers@>=
double mp_get_numeric_value(MP mp,const char *s,size_t l);
int mp_get_boolean_value(MP mp,const char *s,size_t l);
char *mp_get_string_value(MP mp,const char *s,size_t l);
+mp_knot mp_get_path_value(MP mp,const char *s,size_t l);
@ We need to put \MP's ``primitive'' symbolic tokens into the hash
table, together with their command code (which will be the |eq_type|)
@@ -13270,26 +13296,26 @@ static mp_knot mp_offset_prep (MP mp, mp_knot c, mp_knot h) {
c0 = c;
k_needed = 0;
#ifdef DEBUGENVELOPE
-dbg_nl;dbg_str(--[==[BEGIN]==]);dbg_nl;
-dbg_str(return {);dbg_nl;
+dbg_nl;dbg_str(--[==[BEGIN]==]);dbg_nl;
+dbg_str(return {);dbg_nl;
dbg_n(w0->x_coord);
dbg_n(w0->y_coord);
#endif
do {
q = mp_next_knot (p);
#ifdef DEBUGENVELOPE
-dbg_nl;dbg_open_t;dbg_str(--[==[begin loop]==]);dbg_nl;
+dbg_nl;dbg_open_t;dbg_str(--[==[begin loop]==]);dbg_nl;
dbg_n(p->x_coord);dbg_n(p->y_coord);
dbg_n(p->right_x);dbg_n(p->right_y);
dbg_n(q->left_x);dbg_n(q->left_y);
dbg_n(q->x_coord);dbg_n(q->y_coord);
dbg_n(w0->x_coord);
dbg_n(w0->y_coord);
-#endif
+#endif
@<Split the cubic between |p| and |q|, if necessary, into cubics
associated with single offsets, after which |q| should
point to the end of the final such cubic@>;
-#ifdef DEBUGENVELOPE
+#ifdef DEBUGENVELOPE
dbg_key(end Split the cubic between |p| and |q|);dbg_open_t;dbg_nl;
dbg_n(w->x_coord);dbg_n(w->y_coord);
dbg_n(w0->x_coord);dbg_n(w0->y_coord);
@@ -13301,7 +13327,7 @@ dbg_close_t; dbg_comma;dbg_nl;
#ifdef DEBUGENVELOPE
dbg_n(w0->x_coord);dbg_n(w0->y_coord);
dbg_str(--[==[end loop]==]);dbg_nl; dbg_close_t;dbg_comma;dbg_nl;
-#endif
+#endif
} while (q != c);
#ifdef DEBUGENVELOPE
dbg_key(Fix the offset change);dbg_open_t;dbg_nl;
@@ -13312,7 +13338,7 @@ dbg_str(--[==[end loop]==]);dbg_nl; dbg_close_t;dbg_comma;dbg_nl;
#endif
@<Fix the offset change in |mp_knot_info(c)| and set |c| to the return value of
|offset_prep|@>;
-#ifdef DEBUGENVELOPE
+#ifdef DEBUGENVELOPE
dbg_n(p->x_coord);dbg_n(p->y_coord);
dbg_key_ival(info post,mp_knot_info(p));dbg_comma;dbg_nl;
dbg_n(c->x_coord);dbg_n(c->y_coord);
@@ -13412,7 +13438,7 @@ 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...@>=
-#ifdef DEBUGENVELOPE
+#ifdef DEBUGENVELOPE
dbg_comment(Advance |p| to node |q|);dbg_nl;
#endif
q0 = q;
@@ -13437,11 +13463,11 @@ if ((q != q0) && (q != c || c == c0))
@ @<Remove the cubic following |p| and update the data structures...@>=
{
- #ifdef DEBUGENVELOPE
+ #ifdef DEBUGENVELOPE
dbg_key(Remove the cubic following p);dbg_open_t;dbg_nl;
dbg_n(p->x_coord);dbg_n(p->y_coord);
dbg_key_ival(pre info p,mp_knot_info(p)); dbg_close_t;dbg_comma;dbg_nl;
- #endif
+ #endif
k_needed = mp_knot_info (p) - zero_off;
if (r == q) {
q = p;
@@ -13459,11 +13485,11 @@ if ((q != q0) && (q != c || c == c0))
mp->spec_p2 = p;
r = p;
mp_remove_cubic (mp, p);
- #ifdef DEBUGENVELOPE
+ #ifdef DEBUGENVELOPE
dbg_key(Remove the cubic following p);dbg_open_t;dbg_nl;
dbg_n(p->x_coord);dbg_n(p->y_coord);
dbg_key_ival(post info p,mp_knot_info (p)); dbg_close_t;dbg_comma;dbg_nl;
- #endif
+ #endif
}
@@ -13532,16 +13558,16 @@ We may have to split a cubic into many pieces before each
piece corresponds to a unique offset.
@<Split the cubic between |p| and |q|, if necessary, into cubics...@>=
-#ifdef DEBUGENVELOPE
+#ifdef DEBUGENVELOPE
dbg_comment(Split the cubic between |p| and |q|);dbg_nl;
dbg_key(Split the cubic);dbg_open_t;dbg_nl;
dbg_key_ival(pre info p,mp_knot_info(p));dbg_comma;
dbg_n(w0->x_coord);dbg_n(w0->y_coord);
-#endif
+#endif
mp_knot_info (p) = zero_off + k_needed;
-#ifdef DEBUGENVELOPE
+#ifdef DEBUGENVELOPE
dbg_key_ival(post info p,mp_knot_info(p));dbg_close_t;dbg_comma; dbg_nl;
-#endif
+#endif
k_needed = 0;
@<Prepare for derivative computations;
|goto not_found| if the current cubic is dead@>;
@@ -13708,7 +13734,7 @@ void mp_fin_offset_prep (MP mp, mp_knot p, mp_knot w, mp_number
new_number(t2);
new_fraction(s);
new_fraction(t);
-#ifdef DEBUGENVELOPE
+#ifdef DEBUGENVELOPE
dbg_key(mp_fin_offset_prep);dbg_open_t;dbg_nl;
#endif
while (1) {
@@ -13716,7 +13742,7 @@ dbg_key(mp_fin_offset_prep);dbg_open_t;dbg_nl;
ww = mp_next_knot (w); /* a pointer to $w\k$ */
else
ww = mp_prev_knot (w); /* a pointer to $w_{k-1}$ */
-#ifdef DEBUGENVELOPE
+#ifdef DEBUGENVELOPE
dbg_comment(begin iteration);
dbg_open_t;dbg_nl;
dbg_n(w->x_coord);dbg_n(w->y_coord);
@@ -13727,11 +13753,11 @@ dbg_in(rise);
#endif
@<Compute test coefficients |(t0,t1,t2)|
for $d(t)$ versus $d_k$ or $d_{k-1}$@>;
-#ifdef DEBUGENVELOPE
+#ifdef DEBUGENVELOPE
dbg_comment(crossing_point);
#endif
crossing_point (t, t0, t1, t2);
-#ifdef DEBUGENVELOPE
+#ifdef DEBUGENVELOPE
dbg_n(t);dbg_n(t0);dbg_n(t1);dbg_n(t2);
dbg_in(number_greaterequal(t, fraction_one_t));
dbg_in(turn_amt);
@@ -13743,18 +13769,18 @@ dbg_close_t; dbg_comma;dbg_nl;
else
goto RETURN;
}
-#ifdef DEBUGENVELOPE
+#ifdef DEBUGENVELOPE
dbg_comment(Split the cubic at $t$ and split off another cubic if the derivative crosses back);
#endif
@<Split the cubic at $t$,
and split off another cubic if the derivative crosses back@>;
w = ww;
-#ifdef DEBUGENVELOPE
+#ifdef DEBUGENVELOPE
dbg_comment(end iteration);
#endif
}
RETURN:
-#ifdef DEBUGENVELOPE
+#ifdef DEBUGENVELOPE
dbg_comment(RETURN);
dbg_n(t);
#endif
@@ -13766,7 +13792,7 @@ dbg_n(t);
free_number (t0);
free_number (t1);
free_number (t2);
-#ifdef DEBUGENVELOPE
+#ifdef DEBUGENVELOPE
dbg_close_t; dbg_comma;dbg_nl;
#endif
}
@@ -13782,7 +13808,7 @@ begins to fail.
mp_number abs_du, abs_dv;
new_number (abs_du);
new_number (abs_dv);
-#ifdef DEBUGENVELOPE
+#ifdef DEBUGENVELOPE
dbg_key(Compute test coefficients |(t0,t1,t2)| for $d(t)$ versus...);dbg_open_t;dbg_nl;
#endif
set_number_from_substraction(du, ww->x_coord, w->x_coord);
@@ -13791,7 +13817,7 @@ dbg_key(Compute test coefficients |(t0,t1,t2)| for $d(t)$ versus...);dbg_open_t;
number_abs(abs_du);
number_clone(abs_dv, dv);
number_abs(abs_dv);
-#ifdef DEBUGENVELOPE
+#ifdef DEBUGENVELOPE
dbg_CUBIC;
dbg_n(w->x_coord);dbg_n(w->y_coord);
dbg_n(ww->x_coord);dbg_n(ww->y_coord);
@@ -13838,7 +13864,7 @@ dbg_in(number_greaterequal(abs_du, abs_dv));
free_number (abs_dv);
if (number_negative(t0))
set_number_to_zero(t0); /* should be positive without rounding error */
-#ifdef DEBUGENVELOPE
+#ifdef DEBUGENVELOPE
dbg_n(t0);dbg_n(t1);dbg_n(t2);
dbg_close_t; dbg_comma;dbg_nl;
#endif
@@ -13981,19 +14007,19 @@ if (number_zero(dxin) && number_zero(dyin)) {
#ifdef DEBUGENVELOPE
dbg_key(dxin dyin before);dbg_open_t;dbg_nl;
dbg_n(dxin);dbg_n(dyin);
-dbg_close_t;dbg_comma;
+dbg_close_t;dbg_comma;
#endif
#ifdef DEBUGENVELOPE
dbg_key(dxin dyin after);dbg_open_t;dbg_nl;
dbg_n(dxin);dbg_n(dyin);
-dbg_close_t;dbg_comma;
+dbg_close_t;dbg_comma;
#endif
/* BEGIN PATCH */
#ifdef DEBUGENVELOPE
dbg_key(dx dy dxin dyin after patch);dbg_open_t;dbg_nl;
dbg_n(dx);dbg_n(dy);dbg_n(dx_ap);dbg_n(dy_ap);
dbg_n(dxin);dbg_n(dyin);dbg_n(dxin_ap);dbg_n(dyin_ap);
-dbg_close_t;dbg_comma;
+dbg_close_t;dbg_comma;
#endif
/* END PATCH ****/
@@ -14012,13 +14038,13 @@ right.) This code depends on |w0| being the offset for |(dxin,dyin)|.
#ifdef DEBUGENVELOPE
dbg_nl;
dbg_comment(Update |mp_knot_info(p)|);dbg_nl;
-dbg_key(mp_get_turn_amt_dx_dy);dbg_open_t;dbg_str(--[==[call mp_get_turn_amt]==]);dbg_nl;
+dbg_key(mp_get_turn_amt_dx_dy);dbg_open_t;dbg_str(--[==[call mp_get_turn_amt]==]);dbg_nl;
dbg_n(w0->x_coord);dbg_n(w0->y_coord);dbg_n(dx);dbg_n(dy);dbg_in(number_nonnegative(ab_vs_cd));
dbg_n(ab_vs_cd);
#endif
is_dxdy=true;
turn_amt = mp_get_turn_amt (mp, w0, dx, dy, number_nonnegative(ab_vs_cd));
- is_dxdy=false;
+ is_dxdy=false;
#ifdef DEBUGENVELOPE
dbg_dn(turn_amt);
dbg_close_t;dbg_comma;
@@ -14078,20 +14104,20 @@ integer mp_get_turn_amt (MP mp, mp_knot w, mp_number dx, mp_number dy, boolean c
ab_vs_cd (t, dy, arg1, dx, arg2);
#ifdef DEBUGENVELOPE
dbg_sp;
- dbg_open_t;dbg_str(--[==[inside mp_get_turn_amt do loop ]==]);dbg_nl;
+ dbg_open_t;dbg_str(--[==[inside mp_get_turn_amt do loop ]==]);dbg_nl;
dbg_n(w->x_coord);dbg_n(w->y_coord);dbg_n(ww->x_coord);dbg_n(ww->y_coord);
dbg_n(t);dbg_n(dy);dbg_n(arg1);dbg_n(dx);dbg_n(arg2);
dbg_n(t_ap);dbg_n(dy_ap);dbg_n(dx_ap);dbg_n(dyin_ap);dbg_n(dxin_ap);
dbg_close_t;dbg_comma;
dbg_in(number_zero(dx) && number_zero(arg1) && number_positive(dy) && number_positive(arg2) && is_dxdy);
- dbg_in(is_dxdy && number_zero(dx) && number_zero(arg1) && number_negative(dy) && number_negative(arg2) && number_positive(dyin_ap));
+ dbg_in(is_dxdy && number_zero(dx) && number_zero(arg1) && number_negative(dy) && number_negative(arg2) && number_positive(dyin_ap));
dbg_in(is_dxindyin && number_zero(dx) && number_zero(arg1) && number_positive(dy) && number_positive(arg2) && number_negative(dyin_ap));
dbg_in(number_zero(dy) && number_zero(arg2) && number_negative(dx) && number_negative(arg1));
dbg_in(number_zero(dx) && number_zero(arg1) && number_negative(dy) && number_positive(arg2));
dbg_in(number_zero(dy) && number_zero(arg2) && number_positive(dx) && number_negative(arg1));
dbg_nl;
#endif
- if (number_negative(t))
+ if (number_negative(t))
break;
incr (s);
w = ww;
@@ -14104,7 +14130,7 @@ integer mp_get_turn_amt (MP mp, mp_knot w, mp_number dx, mp_number dy, boolean c
ab_vs_cd (t, dy, arg1, dx, arg2);
#ifdef DEBUGENVELOPE
dbg_sp;
- dbg_open_t;dbg_str(--[==[outside mp_get_turn_amt do loop ]==]);dbg_nl;
+ dbg_open_t;dbg_str(--[==[outside mp_get_turn_amt do loop ]==]);dbg_nl;
dbg_n(w->x_coord);dbg_n(w->y_coord);dbg_n(ww->x_coord);dbg_n(ww->y_coord);
dbg_n(t);dbg_n(dy);dbg_n(arg1);dbg_n(dx);dbg_n(arg2);
dbg_n(t_ap);dbg_n(dy_ap);dbg_n(dx_ap);dbg_n(dyin_ap);dbg_n(dxin_ap);
@@ -14120,7 +14146,7 @@ integer mp_get_turn_amt (MP mp, mp_knot w, mp_number dx, mp_number dy, boolean c
ab_vs_cd (t, dy, arg1, dx, arg2);
#ifdef DEBUGENVELOPE
dbg_sp;
- dbg_open_t;dbg_str(--[==[inside mp_get_turn_amt do loop for t<0 ]==]);dbg_nl;
+ dbg_open_t;dbg_str(--[==[inside mp_get_turn_amt do loop for t<0 ]==]);dbg_nl;
dbg_n(w->x_coord);dbg_n(w->y_coord);dbg_n(ww->x_coord);dbg_n(ww->y_coord);
dbg_n(t);dbg_n(dy);dbg_n(arg1);dbg_n(dx);dbg_n(arg2);
dbg_n(t_ap);dbg_n(dy_ap);dbg_n(dx_ap);
@@ -14173,14 +14199,14 @@ with respect to $d_{k-1}$, and apply |fin_offset_prep| to each part.
@<Complete the offset splitting process@>=
ww = mp_prev_knot (w);
-#ifdef DEBUGENVELOPE
+#ifdef DEBUGENVELOPE
dbg_key(Complete the offset splitting process);dbg_open_t;dbg_nl;
dbg_n(w->x_coord);dbg_n(w->y_coord);
dbg_n(ww->x_coord);dbg_n(ww->y_coord);
dbg_close_t; dbg_comma;dbg_nl;
#endif
@<Compute test coeff...@>;
-#ifdef DEBUGENVELOPE
+#ifdef DEBUGENVELOPE
dbg_key(after Compute test coeff);dbg_open_t;dbg_nl;
dbg_n(w->x_coord);dbg_n(w->y_coord);
dbg_n(ww->x_coord);dbg_n(ww->y_coord);
@@ -14189,7 +14215,7 @@ dbg_close_t; dbg_comma;dbg_nl;
@<Find the first |t| where $d(t)$ crosses $d_{k-1}$ or set
|t:=fraction_one+1|@>;
if (number_greater(t, fraction_one_t)) {
-#ifdef DEBUGENVELOPE
+#ifdef DEBUGENVELOPE
dbg_key(t > fraction_one_t);dbg_open_t;dbg_nl;
dbg_n(p->x_coord);dbg_n(p->y_coord);
dbg_n(w->x_coord);dbg_n(w->y_coord);
@@ -14207,7 +14233,7 @@ dbg_close_t; dbg_comma;dbg_nl;
set_number_from_of_the_way(y1a, t, y0, y1);
set_number_from_of_the_way(y1, t, y1, y2);
set_number_from_of_the_way(y2a, t, y1a, y1);
-#ifdef DEBUGENVELOPE
+#ifdef DEBUGENVELOPE
dbg_key(t <= fraction_one_t);dbg_open_t;dbg_nl;
dbg_n(p->x_coord);dbg_n(p->y_coord);
dbg_n(t);
@@ -14245,7 +14271,7 @@ dbg_close_t; dbg_comma;dbg_nl;
mp_fin_offset_prep (mp, r, ww, x0, x1, x2, y0, y1, y2, -1, (-1 - turn_amt));
}
}
-#ifdef DEBUGENVELOPE
+#ifdef DEBUGENVELOPE
dbg_key(end Complete the offset splitting process);dbg_open_t;dbg_nl;
dbg_n(w->x_coord);dbg_n(w->y_coord);
dbg_n(w0->x_coord);dbg_n(w0->y_coord);
@@ -14278,7 +14304,7 @@ crossing and the first crossing cannot be antiparallel.
@<Find the first |t| where $d(t)$ crosses $d_{k-1}$ or set...@>=
#ifdef DEBUGENVELOPE
dbg_key(Find the first |t| where);dbg_open_t;dbg_nl;
-#endif
+#endif
crossing_point (t, t0, t1, t2);
if (turn_amt >= 0) {
if (number_negative(t2)) {
@@ -14316,7 +14342,7 @@ if (turn_amt >= 0) {
#ifdef DEBUGENVELOPE
dbg_n(t);
dbg_close_t; dbg_comma;dbg_nl;
-#endif
+#endif
@ @<Other local variables for |offset_prep|@>=
@@ -19845,6 +19871,7 @@ is less than |loop_text|.
@ @<Run a script@>=
if (s != NULL) {
int k ;
+ mp_value new_expr;
size_t size = strlen(s);
memset(&new_expr,0,sizeof(mp_value));
new_number(new_expr.data.n);
@@ -19860,7 +19887,6 @@ if (s != NULL) {
}
limit = (halfword) k;
(void) memcpy ((mp->buffer + mp->first), s, size);
- free(s);
mp->buffer[limit] = xord ('%');
mp->first = (size_t) (limit + 1);
loc = start;
@@ -19891,26 +19917,42 @@ if (s != NULL) {
} else {
mp_back_input (mp);
if (cur_exp_str ()->len > 0) {
- mp_value new_expr;
char *s = mp->run_script(mp,(const char*) cur_exp_str()->str) ;
@<Run a script@>
+ free(s);
}
}
}
-@ @<Pass btex ... etex to script@>=
+@ The |texscriptmode| parameter controls how spaces and newlines get honoured in
+|btex| or |verbatimtex| ... |etex|. The default value is~1. Possible values are:
+0: no newlines, 1: newlines in |verbatimtex|, 2: newlines in |verbatimtex| and
+|etex|, 3: no leading and trailing strip in |verbatimtex|, 4: no leading and
+trailing strip in |verbatimtex| and |btex|. That way the Lua handler can do what
+it likes. An |etex| has to be followed by a space or |;| or be at the end of a
+line and preceded by a space or at the beginning of a line.
+
+@<Pass btex ... etex to script@>=
{
- int first ;
- while ((loc < limit - 4) && (mp->buffer[loc] == ' ')) {
+ char *txt = NULL;
+ char *ptr = NULL;
+ int slin = line;
+ int size = 0;
+ int done = 0;
+ int mode = round_unscaled(internal_value(mp_texscriptmode)) ; /* default: 1 */
+ int verb = cur_mod() == verbatim_code;
+ int first;
+ /* we had a (mandate) trailing space */
+ if (loc <= limit && mp->char_class[mp->buffer[loc]] == space_class) {
incr(loc);
+ } else {
+ /* maybe issue an error message and quit */
}
- first = loc ;
- if (mp->buffer[loc-1] == ' ') {
- decr(loc);
- }
- while (loc < limit - 5) {
- if (mp->buffer[loc] == ' ') {
- incr(loc);
+ /* we loop over lines */
+ first = loc;
+ while (1) {
+ /* we don't need to check when we have less than 4 characters left */
+ if (loc < limit - 4) {
if (mp->buffer[loc] == 'e') {
incr(loc);
if (mp->buffer[loc] == 't') {
@@ -19918,39 +19960,135 @@ if (s != NULL) {
if (mp->buffer[loc] == 'e') {
incr(loc) ;
if (mp->buffer[loc] == 'x') {
- /* start action */
- char *s, *txt ;
- int size ;
- mp_value new_expr;
- size = loc - first + 1 - 4 ;
- if (size < 0) {
- size = 0 ;
- } else {
- while ((size > 1) && (mp->buffer[first+size-1] == ' ')) {
- decr(size);
- }
+ /* let's see if we have the right boundary */
+ if (first == (loc - 3)) {
+ /* when we're at the start of a line no leading space is required */
+ done = 1;
+ } else if (mp->char_class[mp->buffer[loc - 4]] == space_class) {
+ /* when we're beyond the start of a line a leading space is required */
+ done = 2;
}
- txt = malloc(size+1);
- if (size > 0) {
- (void) memcpy (txt, mp->buffer + first, size);
+ if (done) {
+ if ((loc + 1) <= limit) {
+ quarterword c = mp->char_class[mp->buffer[loc + 1]] ;
+ if (c != letter_class) {
+ incr(loc) ;
+ /* we're past the 'x' */
+ break;
+ } else {
+ /* this is no valid etex */
+ done = 0;
+ }
+ } else {
+ /* when we're at the end of a line we're ok */
+ incr(loc) ;
+ /* we're past the 'x' */
+ break;
+ }
}
- txt[size] = '\0';
- incr(loc);
- s = mp->make_text(mp,txt,(cur_mod() == verbatim_code)) ; /* we could pass the size */
- @<Run a script@>
- /* done */
- free(txt);
- break ;
- } else {
- // decr(loc) ;
}
}
}
}
+ }
+ /* no etex seen (yet) */
+ if (loc >= limit) {
+ if (size) {
+ txt = realloc(txt, size + limit - first + 1);
+ } else {
+ txt = malloc(limit - first + 1);
+ }
+ (void) memcpy (txt + size, mp->buffer + first, limit - first);
+ size += limit - first + 1;
+ if (mode <= 0) {
+ txt[size - 1] = ' ';
+ } else if (verb) {
+ /* modes >= 1 permit a newline in verbatimtex */
+ txt[size - 1] = '\n';
+ } else if (mode >= 2) {
+ /* modes >= 2 permit a newline in btex */
+ txt[size - 1] = '\n';
+ } else {
+ txt[size - 1] = ' ';
+ }
+ if (move_to_next_line(mp)) {
+ /* we abort the scanning */
+ goto FATAL_ERROR;
+ }
+ first = loc;
} else {
incr(loc);
}
}
+ if (done) {
+ /* we're past the 'x' */
+ int l = loc - 5 ; // 4
+ int n = l - first + 1 ;
+ /* we're before the 'etex' */
+ if (done == 2) {
+ /* we had ' etex' */
+ l -= 1;
+ n -= 1;
+ /* we're before the ' etex' */
+ }
+ if (size) {
+ txt = realloc(txt, size + n + 1);
+ } else {
+ txt = malloc(n + 1);
+ }
+ (void) memcpy (txt + size, mp->buffer + first, n); /* 0 */
+ size += n;
+ if (verb && mode >= 3) {
+ /* don't strip verbatimtex */
+ txt[size] = '\0';
+ ptr = txt;
+ } else if (mode >= 4) {
+ /* don't strip btex */
+ txt[size] = '\0';
+ ptr = txt;
+ } else {
+ /* strip trailing whitespace, we have a \0 so we're one off */
+ /* while ((size > 1) && (mp->char_class[(ASCII_code) txt[size-2]] == space_class || txt[size-2] == '\n')) { */
+ while ((size > 1) && (mp->char_class[(ASCII_code) txt[size-1]] == space_class || txt[size-1] == '\n')) {
+ decr(size);
+ }
+ /* prune the string */
+ txt[size] = '\0';
+ /* strip leading whitespace */
+ ptr = txt;
+ while ((size > 1) && (mp->char_class[(ASCII_code) ptr[0]] == space_class || ptr[0] == '\n')) {
+ incr(ptr);
+ decr(size);
+ }
+ }
+ /* action */
+ {
+ char *s = mp->make_text(mp,ptr,verb) ;
+ @<Run a script@>
+ free(s);
+ }
+ free(txt);
+ /* really needed */
+ mp_get_next(mp);
+ return;
+ }
+ /*
+ we don't recover because in practice the graphic will be broken anyway and
+ we're not really interacting in mplib .. just fix the input
+ */
+ FATAL_ERROR:
+ {
+ /* line numbers are not always meaningfull so we can get a 0 reported */
+ char msg[256];
+ const char *hlp[] = { "An 'etex' is missing at this input level, nothing gets done.", NULL };
+ if (slin > 0) {
+ mp_snprintf(msg, 256, "No matching 'etex' for '%stex'.", verb ? "verbatim" : "b");
+ } else {
+ mp_snprintf(msg, 256, "No matching 'etex' for '%stex' in line %d.", verb ? "verbatim" : "b",slin);
+ }
+ mp_error (mp, msg, hlp, false);
+ free(txt);
+ }
}
@ @<Put a maketext result string into the input buffer@>=
@@ -19964,7 +20102,7 @@ if (s != NULL) {
mp_value new_expr;
const char *hlp[] = {
"I'm going to flush this expression, since",
- "makete should be followed by a known string.",
+ "maketext should be followed by a known string.",
NULL };
memset(&new_expr,0,sizeof(mp_value));
new_number(new_expr.data.n);
@@ -19976,9 +20114,9 @@ if (s != NULL) {
} else {
mp_back_input (mp);
if (cur_exp_str ()->len > 0) {
- mp_value new_expr;
char *s = mp->make_text(mp,(const char*) cur_exp_str()->str,0) ;
@<Run a script@>
+ free(s);
}
}
}
@@ -23295,7 +23433,7 @@ RESTART:
q = mp_get_value_node (mp);
mp_name_type (q) = mp_capsule;
- if (cur_cmd() == mp_comma) {
+ if (cur_cmd() == mp_comma) {
mp_init_color_node (mp, q);
r = value_node (q);
mp_stash_in (mp, y_part (r));
@@ -23321,7 +23459,7 @@ RESTART:
}
mp_stash_in (mp, blue_part (r));
- if (cur_cmd() == mp_comma) {
+ if (cur_cmd() == mp_comma) {
mp_node t; /* a token */
mp_init_cmykcolor_node (mp, q);
t = value_node (q);
@@ -23337,13 +23475,13 @@ RESTART:
set_dep_list (cyan_part(t),dep_list ((mp_value_node) red_part(r)));
set_prev_dep (cyan_part(t),prev_dep ((mp_value_node) red_part(r)));
set_mp_link (prev_dep (cyan_part(t)), (mp_node) cyan_part(t));
- }
+ }
if ( ((mp_type (magenta_part (t))) != mp_independent) && ((mp_type (magenta_part (t))) != mp_known) ) {
/* Copy the dep list */
set_dep_list (magenta_part(t),dep_list ((mp_value_node) green_part(r)));
set_prev_dep (magenta_part(t),prev_dep ((mp_value_node) green_part(r)));
set_mp_link (prev_dep (magenta_part(t)), (mp_node) magenta_part(t));
- }
+ }
if ( ((mp_type (yellow_part (t))) != mp_independent) && ((mp_type (yellow_part (t))) != mp_known)) {
/* Copy the dep list */
set_dep_list (yellow_part(t),dep_list ((mp_value_node) blue_part(r)));
@@ -28985,7 +29123,7 @@ static void mp_set_up_boundingpath (MP mp, mp_node p) {
unsigned char ljoin, lcap;
mp_number miterlim;
mp_knot q = mp_copy_path (mp, cur_exp_knot ()); /* the original path */
- mp_knot pen;
+ mp_knot pen;
mp_knot qq;
new_number(miterlim);
@@ -30671,8 +30809,8 @@ void mp_show_library_versions (void) {
fprintf(stdout, "Compiled with pixman %s; using %s\n",COMPILED_PIXMAN_VERSION_STRING, pixman_version_string());
fprintf(stdout, "Compiled with libpng %s; using %s\n", PNG_LIBPNG_VER_STRING, png_libpng_ver);
fprintf(stdout, "Compiled with zlib %s; using %s\n", ZLIB_VERSION, zlibVersion());
- fprintf(stdout, "Compiled with mpfr %s; using %s\n", MPFR_VERSION_STRING, mpfr_get_version());
- fprintf(stdout, "Compiled with gmp %d.%d.%d; using %s\n\n", __GNU_MP_VERSION, __GNU_MP_VERSION_MINOR, __GNU_MP_VERSION_PATCHLEVEL, gmp_version);
+ fprintf(stdout, "Compiled with mpfr %s; using %s\n", COMPILED_MPFR_VERSION_STRING, mpfr_get_version());
+ fprintf(stdout, "Compiled with gmp %d.%d.%d; using %s\n\n", COMPILED__GNU_MP_VERSION, COMPILED__GNU_MP_VERSION_MINOR, COMPILED__GNU_MP_VERSION_PATCHLEVEL, COMPILED_gmp_version);
}
@ @<Exported function headers@>=
@@ -33230,7 +33368,7 @@ We may need to cancel skips that span more than 127 lig/kern steps.
@ The header could contain ASCII zeroes, so can't use |strdup|.
-The index |j| can be beyond the index |header_last|, hence we
+The index |j| can be beyond the index |header_last|, hence we
have to sure to update the end of stream marker to reflect the
actual position.
@@ -34555,8 +34693,9 @@ extreme cases so it may have to be shortened on some systems.
@<Use |c| to compute the file extension |s|@>=
{
- s = xmalloc (7, 1);
- mp_snprintf (s, 7, ".%i", (int) c);
+ s = xmalloc (12, 1);
+ mp_snprintf (s, 12, ".%i", (int) c);
+ s[7]='\0';
}