texlive[42088] Build/source/texk/web2c/mplibdir: mplibdir: sync with

commits+kakuto at tug.org commits+kakuto at tug.org
Sat Sep 17 09:59:22 CEST 2016


Revision: 42088
          http://tug.org/svn/texlive?view=revision&revision=42088
Author:   kakuto
Date:     2016-09-17 09:59:22 +0200 (Sat, 17 Sep 2016)
Log Message:
-----------
mplibdir: sync with the upstream

Modified Paths:
--------------
    trunk/Build/source/texk/web2c/mplibdir/mp.w
    trunk/Build/source/texk/web2c/mplibdir/mpmathbinary.w
    trunk/Build/source/texk/web2c/mplibdir/mpmathdecimal.w
    trunk/Build/source/texk/web2c/mplibdir/mpmathdouble.w

Modified: trunk/Build/source/texk/web2c/mplibdir/mp.w
===================================================================
--- trunk/Build/source/texk/web2c/mplibdir/mp.w	2016-09-17 01:10:34 UTC (rev 42087)
+++ trunk/Build/source/texk/web2c/mplibdir/mp.w	2016-09-17 07:59:22 UTC (rev 42088)
@@ -1,4 +1,4 @@
-% $Id: mp.w 2089 2016-08-22 09:42:23Z luigi $
+% $Id: mp.w 2091 2016-09-16 23:07:58Z luigi $
 %
 % This file is part of MetaPost;
 % the MetaPost program is in the public domain.
@@ -140,6 +140,19 @@
 #endif
 
 @ @c
+/*#define DEBUGENVELOPE */
+#ifdef DEBUGENVELOPE 
+#define dbg_n(A) printf("['%s']=%s, ", #A, number_tostring(A))
+#define dbg_in(A) printf("['%s']=%d, ", #A, (int)(A))
+#define dbg_dn(A) printf("['%s']=%.100f, ", #A, (double)(A))
+#define dbg_key(A) printf("['%s']= ", #A)
+#define dbg_sp printf(" ")
+#define dbg_str(A) printf("%s",#A)
+#define dbg_open_t printf("{")
+#define dbg_close_t printf("}")
+#define dbg_comma printf(",")
+#define dbg_nl printf("\n")
+#endif
 #define KPATHSEA_DEBUG_H 1
 #include <w2c/config.h>
 #include <stdio.h>
@@ -171,6 +184,15 @@
 #include "mpmathdecimal.h"      /* internal header */
 #include "mpmathbinary.h"       /* internal header */
 #include "mpstrings.h"          /* internal header */
+/* BEGIN PATCH */
+mp_number dx_ap;    /* approximation of dx */
+mp_number dy_ap;    /* approximation of dy */
+mp_number dxin_ap;  /* approximation of dxin */
+mp_number dyin_ap;  /* approximation of dyin */
+mp_number ueps_ap;  /* epsilon for above approximations */
+/* END PATCH */
+
+
 extern font_number mp_read_font_info (MP mp, char *fname);      /* tfmin.w */
 @h @<Declarations@>;
 @<Basic printing procedures@>;
@@ -2568,18 +2590,18 @@
   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.
 
 @c
 /* Unused.
-static void mp_next_random (MP mp, mp_number *ret) {
-  if ( mp->j_random==0 )
-    mp_new_randoms(mp);
+static void mp\_next\_random (MP mp, mp\_number *ret) {
+  if ( mp->j\_random==0 )
+    mp\_new\_randoms(mp);
   else
-    decr(mp->j_random);
-  number_clone (*ret, mp->randoms[mp->j_random]);
+    decr(mp->j\_random);
+  number\_clone (*ret, mp->randoms[mp->j\_random]);
 }
 */
 
@@ -2596,31 +2618,31 @@
 
 @c
 /*Unused.
-static void mp_unif_rand (MP mp, mp_number *ret, mp_number x_orig) {
-  mp_number y;     // trial value
-  mp_number x, abs_x;
-  mp_number u;
-  new_fraction (y);
-  new_number (x);
-  new_number (abs_x);
-  new_number (u);
-  number_clone (x, x_orig);
-  number_clone (abs_x, x);
-  number_abs (abs_x);
-  mp_next_random(mp, &u);
-  take_fraction (y, abs_x, u);
-  free_number (u);
-  if (number_equal(y, abs_x)) {
-    set_number_to_zero(*ret);
-  } else if (number_positive(x)) {
-    number_clone (*ret, y);
+static void mp\_unif\_rand (MP mp, mp\_number *ret, mp\_number x\_orig) {
+  mp\_number y;     // trial value 
+  mp\_number x, abs\_x;
+  mp\_number u;
+  new\_fraction (y);
+  new\_number (x);
+  new\_number (abs\_x);
+  new\_number (u);
+  number\_clone (x, x\_orig);
+  number\_clone (abs\_x, x);
+  number\_abs (abs\_x);
+  mp\_next\_random(mp, \&u);
+  take\_fraction (y, abs\_x, u);
+  free\_number (u);
+  if (number\_equal(y, abs\_x)) {
+    set\_number\_to\_zero(*ret);
+  } else if (number\_positive(x)) {
+    number\_clone (*ret, y);
   } else {
-    number_clone (*ret, y);
-    number_negate (*ret);
+    number\_clone (*ret, y);
+    number\_negate (*ret);
   }
-  free_number (abs_x);
-  free_number (x);
-  free_number (y);
+  free\_number (abs\_x);
+  free\_number (x);
+  free\_number (y);
 }
 */
 
@@ -2634,43 +2656,43 @@
 
 @c
 /*  Unused.
-static void mp_norm_rand (MP mp, mp_number *ret) {
-  mp_number ab_vs_cd;
-  mp_number abs_x;
-  mp_number u;
-  mp_number r;
-  mp_number la, xa;
-  new_number (ab_vs_cd);
-  new_number (la);
-  new_number (xa);
-  new_number (abs_x);
-  new_number (u);
-  new_number (r);
+static void mp\_norm\_rand (MP mp, mp\_number *ret) {
+  mp\_number ab\_vs\_cd;
+  mp\_number abs\_x;
+  mp\_number u;
+  mp\_number r;
+  mp\_number la, xa;
+  new\_number (ab\_vs\_cd);
+  new\_number (la);
+  new\_number (xa);
+  new\_number (abs\_x);
+  new\_number (u);
+  new\_number (r);
   do {
     do {
-      mp_number v;
-      new_number (v);
-      mp_next_random(mp, &v);
-      number_substract (v, fraction_half_t);
-      take_fraction (xa, sqrt_8_e_k, v);
-      free_number (v);
-      mp_next_random(mp, &u);
-      number_clone (abs_x, xa);
-      number_abs (abs_x);
-    } while (number_greaterequal (abs_x, u));
-    make_fraction (r, xa, u);
-    number_clone (xa, r);
-    m_log (la, u);
-    set_number_from_substraction(la, twelve_ln_2_k, la);
-    ab_vs_cd (ab_vs_cd, one_k, la, xa, xa);
-  } while (number_negative(ab_vs_cd));
-  number_clone (*ret, xa);
-  free_number (ab_vs_cd);
-  free_number (r);
-  free_number (abs_x);
-  free_number (la);
-  free_number (xa);
-  free_number (u);
+      mp\_number v;
+      new\_number (v);
+      mp\_next\_random(mp, \&v);
+      number\_substract (v, fraction\_half\_t);
+      take\_fraction (xa, sqrt\_8\_e\_k, v);
+      free\_number (v);
+      mp\_next\_random(mp, \&u);
+      number\_clone (abs\_x, xa);
+      number\_abs (abs\_x);
+    } while (number\_greaterequal (abs\_x, u));
+    make\_fraction (r, xa, u);
+    number\_clone (xa, r);
+    m\_log (la, u);
+    set\_number\_from\_substraction(la, twelve\_ln\_2\_k, la);
+    ab\_vs\_cd (ab\_vs\_cd, one\_k, la, xa, xa);
+  } while (number\_negative(ab\_vs\_cd));
+  number\_clone (*ret, xa);
+  free\_number (ab\_vs\_cd);
+  free\_number (r);
+  free\_number (abs\_x);
+  free\_number (la);
+  free\_number (xa);
+  free\_number (u);
 }
 */
 
@@ -4705,7 +4727,7 @@
   return mp_do_id_lookup (mp, mp->frozen_symbols, j, l, insert_new);
 }
 
-/* see mp_print_sym  (mp_sym sym) */
+/* see mp\_print\_sym  (mp\_sym sym) */
 @ Get a numeric value from \MP\ is not easy. We have to consider
 the macro and the loops, as also the internal type (this is a
 first attempt, and more work is needed). If we are inside
@@ -13144,7 +13166,119 @@
 @<Glob...@>=
 integer spec_offset;    /* number of pen edges between |h| and the initial offset */
 
+@ The next function calculates $1/3 B'(t) =   (-p + (3*c1 + (-3*c2 + q)))*t^2 + (2*p + (-4*c1 + 2*c2))*t + (-p + c1)$,
+and it's used for |t| near 0 and |t| near 1.
+
+@<Declarations@>=
+static void mp_dx_dy_approx(MP mp, mp_number *dx_ap, mp_number *dy_ap,mp_knot p, mp_knot q,mp_number t);
+
 @ @c
+static void mp_dx_dy_approx(MP mp, mp_number *dx_ap, mp_number *dy_ap,mp_knot kp, mp_knot kq,mp_number t) { /* find dx dy at |t| */
+
+  /* 1/3 B'(t) =   (-p + (3c1 + (-3c2 + q)))t^2 + (2p + (-4c1 + 2c2))*t + (-p + c1) */   
+  mp_number p,c1,c2,q;
+  mp_number s1,s2,s3;
+  mp_number absval;
+  mp_number max_coef;       /* used while scaling */
+  mp_number small_nr, big_nr;
+  mp_number abs_dx, abs_dy;
+
+  new_number(p);
+  new_number(c1);
+  new_number(c2);
+  new_number(q);
+  new_number(s1);
+  new_number(s2);
+  new_number(s3);
+  new_number (absval);
+  new_number(max_coef);
+  new_number(small_nr);
+  new_number(big_nr);
+  new_number(abs_dx);
+  new_number(abs_dy);
+  
+  set_number_from_double(small_nr,0.001);
+  set_number_from_double(big_nr,1000);
+  
+  number_clone (p,kp->x_coord);
+  number_clone (c1,kp->right_x);
+  number_clone (c2,kq->left_x);
+  number_clone (q,kq->x_coord);
+
+  number_clone (s1,p);
+  number_negate (s1);
+  number_add (s1,c1);number_add (s1,c1);number_add (s1,c1);
+  number_substract(s1,c2);number_substract (s1,c2);number_substract (s1,c2); 
+  number_add (s1,q);
+  set_number_from_mul(s1,s1,t);set_number_from_mul(s1,s1,t);
+  number_clone (s2,p);  number_add (s2,p);
+  number_substract(s2,c1);number_substract (s2,c1);number_substract (s2,c1);number_substract (s2,c1); 
+  number_add (s2,c2);number_add (s2,c2);  
+  set_number_from_mul (s2,s2,t);
+  number_clone (s3,c1);  
+  number_substract(s3,p);
+  number_add (s3,s2);
+  number_add (s3,s1);
+  number_clone(*dx_ap,s3);
+
+  number_clone(p,kp->y_coord);
+  number_clone(c1,kp->right_y);
+  number_clone(c2,kq->left_y);
+  number_clone(q,kq->y_coord);
+
+  number_clone (s1,p);
+  number_negate (s1);
+  number_add (s1,c1);number_add (s1,c1);number_add (s1,c1);
+  number_substract(s1,c2);number_substract (s1,c2);number_substract (s1,c2); 
+  number_add (s1,q);
+  set_number_from_mul(s1,s1,t);set_number_from_mul(s1,s1,t);
+  number_clone (s2,p);  number_add (s2,p);
+  number_substract(s2,c1);number_substract (s2,c1);number_substract (s2,c1);number_substract (s2,c1); 
+  number_add (s2,c2);number_add (s2,c2);  
+  set_number_from_mul (s2,s2,t);
+  number_clone (s3,c1);  
+  number_substract(s3,p);
+  number_add (s3,s2);
+  number_add (s3,s1);
+  number_clone(*dy_ap,s3);
+
+
+  if (!number_zero(*dx_ap) || !number_zero(*dy_ap)) {
+    number_clone(absval, *dx_ap);
+    number_abs(absval);
+    number_clone(max_coef, *dy_ap);
+    number_abs (max_coef);
+    if (number_greater(absval, max_coef)) {
+      number_clone(max_coef, absval);
+    }
+    while (number_less(max_coef, fraction_half_t)) {
+      number_double (max_coef);
+      number_double (*dx_ap);
+      number_double (*dy_ap);
+    } 
+    number_clone(abs_dx,*dx_ap);
+    number_clone(abs_dy,*dy_ap);
+    number_abs(abs_dx);
+    number_abs(abs_dy);
+    /* This is an experimental approximation */
+    /* We should put a warning here */
+    if (number_greaterequal(abs_dy,big_nr) && number_lessequal(abs_dx,small_nr)) {
+      set_number_to_zero(*dx_ap);
+    }
+    if (number_greaterequal(abs_dx,big_nr) && number_lessequal(abs_dy,small_nr)) {
+      set_number_to_zero(*dy_ap);
+    }
+  }
+  free_number(p);
+  free_number(c1);
+  free_number(c2);
+  free_number(q);
+  free_number(s1);
+  free_number(s2);
+  free_number(s3);
+}
+
+@ @c
 static mp_knot mp_offset_prep (MP mp, mp_knot c, mp_knot h) {
   int n;   /* the number of vertices in the pen polygon */
   mp_knot c0, p, q, q0, r, w, ww;       /* for list manipulation */
@@ -13183,6 +13317,13 @@
   new_number(u1);
   new_number(v0);
   new_number(v1);
+  new_number(dx_m);
+  new_number(dxin_m);
+  new_number(dx_ap);
+  new_number(dy_ap);
+  new_number(dxin_ap);
+  new_number(dyin_ap);
+  new_number(ueps_ap);
   new_fraction (ss);
   new_fraction (s);
   new_fraction (t);
@@ -13191,8 +13332,18 @@
   p = c;
   c0 = c;
   k_needed = 0;
-  do {
+#ifdef DEBUGENVELOPE
+dbg_nl;dbg_str(--[==[BEGIN]==]);dbg_nl; 
+#endif
+ do {
     q = mp_next_knot (p);
+#ifdef DEBUGENVELOPE
+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);
+#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@>;
@@ -13199,9 +13350,21 @@
   NOT_FOUND:
     @<Advance |p| to node |q|, removing any ``dead'' cubics that
       might have been introduced by the splitting process@>;
+#ifdef DEBUGENVELOPE
+dbg_str(--[==[end loop]==]);dbg_nl; dbg_close_t;dbg_comma;dbg_nl;
+#endif 
   } while (q != c);
+#ifdef DEBUGENVELOPE
+ dbg_key(Fix the offset change);dbg_open_t;dbg_nl;
+  dbg_in(mp_knot_info(p));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  
+dbg_in(mp_knot_info(p));
+dbg_close_t;dbg_comma;dbg_nl;
+dbg_nl;dbg_str(--[==[END]==]);dbg_nl;
+#endif
   free_number (ss);
   free_number (s);
   free_number (dxin);
@@ -13232,6 +13395,13 @@
   free_number (u1);
   free_number (v0);
   free_number (v1);
+  free_number(dx_m);
+  free_number(dxin_m);
+  free_number(dx_ap);
+  free_number(dy_ap);
+  free_number(dxin_ap);
+  free_number(dyin_ap);
+  free_number(ueps_ap);
   free_number (t);
   return c;
 }
@@ -13447,7 +13617,10 @@
 mp_number x0a, x1a, x2a, y0a, y1a, y2a;   /* intermediate values */
 mp_number t;     /* where the derivative passes through zero */
 mp_number s;     /* a temporary value */
+mp_number dx_m;     /* signal a pertubation of dx */
+mp_number dxin_m;   /* signal a pertubation of dxin */
 
+
 @ @<Prepare for derivative computations...@>=
 set_number_from_substraction(x0, p->right_x, p->x_coord);
 set_number_from_substraction(x2, q->x_coord, q->left_x);
@@ -13455,6 +13628,11 @@
 set_number_from_substraction(y0, p->right_y, p->y_coord);
 set_number_from_substraction(y2, q->y_coord, q->left_y);
 set_number_from_substraction(y1, q->left_y, p->right_y);
+#ifdef DEBUGENVELOPE
+dbg_key(Prepare for derivative computations);dbg_open_t;dbg_nl;
+dbg_n(x0);dbg_n(y0);dbg_n(x1);dbg_n(y1);dbg_n(x2);dbg_n(y2);
+dbg_close_t;dbg_comma;dbg_nl;
+#endif
 {
   mp_number absval;
   new_number (absval);
@@ -13698,6 +13876,7 @@
 degenerate.
 
 @<Find the initial direction |(dx,dy)|@>=
+number_clone(dx_m, zero_t);
 number_clone(dx, x0);
 number_clone(dy, y0);
 if (number_zero(dx) && number_zero(dy)) {
@@ -13712,8 +13891,71 @@
   number_clone(dx0, dx);
   number_clone(dy0, dy);
 }
+/* BEGIN PATCH */
+set_number_from_substraction(ueps_ap,unity_t,epsilon_t); /* |1-eps| */
+#ifdef DEBUGENVELOPE
+dbg_nl;dbg_key(mp_dx_dy_approx_t_1);dbg_open_t;dbg_nl;
+dbg_n(ueps_ap);
+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);
+#endif
+mp_dx_dy_approx(mp,&dxin_ap,&dyin_ap,p,q,ueps_ap);
+#ifdef DEBUGENVELOPE
+dbg_n(dxin_ap);dbg_n(dyin_ap);
+dbg_close_t;dbg_comma;dbg_nl;
+#endif
+/**/
+number_clone(ueps_ap,epsilon_t); 
+#ifdef DEBUGENVELOPE
+dbg_nl;dbg_key(mp_dx_dy_approx_t_0);dbg_open_t;dbg_nl;
+dbg_n(ueps_ap);
+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);
+#endif
+mp_dx_dy_approx(mp,&dx_ap,&dy_ap,p,q,ueps_ap); /*|eps|*/
+#ifdef DEBUGENVELOPE
+dbg_n(dx_ap);dbg_n(dy_ap);
+dbg_close_t;dbg_comma;dbg_nl;
+dbg_key(derivatives);dbg_open_t;dbg_nl;
+dbg_n(dx);dbg_n(dy);dbg_n(dx_ap);dbg_n(dy_ap);dbg_close_t;dbg_comma;dbg_nl;
+#endif
+/* BEGIN PATCH */
+if (number_zero(dx) && !(number_zero(dy)) && number_zero(x0) && number_zero(x2) && !number_zero(dxin) ){
+    number_clone(dx_m, epsilon_t);
+    if (number_positive(x1)){      
+     set_number_from_addition (dx, dx, epsilon_t); 
+    } else if (number_negative(x1)) {
+     set_number_from_substraction (dx, dx, epsilon_t);  
+    }
+} 
+/* hm what about dx=dy=0 ? */
+if (number_zero(dx_ap) && !number_zero(dx)){
+  set_number_to_zero(dx);
+  if (p == c) {
+    set_number_to_zero(dx0);
+    }
+  mp_warn(mp,"x component of derivative at t=0 approximated to zero.");
+ } 
+if (number_zero(dy_ap) && !number_zero(dy)){
+  set_number_to_zero(dy);
+  if (p == c) {
+    set_number_to_zero(dy0);
+    }
+  mp_warn(mp,"y component of derivative at t=0 approximated to zero.");
+ } 
+#ifdef DEBUGENVELOPE
+dbg_key(derivatives patched);dbg_open_t;dbg_nl;
+dbg_n(dx);dbg_n(dy);dbg_n(dx_ap);dbg_n(dy_ap);dbg_close_t;dbg_comma;dbg_nl;
+#endif
+/* END PATCH */
 
+
 @ @<Find the final direction |(dxin,dyin)|@>=
+number_clone(dxin_m, zero_t);
 number_clone(dxin, x2);
 number_clone(dyin, y2);
 if (number_zero(dxin) && number_zero(dyin)) {
@@ -13724,6 +13966,45 @@
     number_clone(dyin, y0);
   }
 }
+if (number_zero(dxin_ap) && !number_zero(dxin)){
+  set_number_to_zero(dxin);
+  mp_warn(mp,"x component of derivative at t=1 approximated at zero");
+ } 
+if (number_zero(dyin_ap) && !number_zero(dyin)){
+  set_number_to_zero(dyin);
+  mp_warn(mp,"y component of derivative at t=1 approximated at zero");
+ } 
+#ifdef DEBUGENVELOPE
+dbg_key(dxin dyin);dbg_open_t;dbg_nl;
+dbg_n(dxin);dbg_n(dyin);
+dbg_close_t;dbg_comma; 
+#endif
+/* BEGIN PATCH \par
+$ 1/3 B'(t,X_0,X_1,X_2) = (1-t)^2X_0+2(1-t)tX_1+3t^2X_2 $ \par
+$ 1/3 B'(t,X_0,X_1,X_2) = (X_0 + (-2X_1 + X_2))t^2 + (-2X_0 + 2X_1)t + X_0 $ \par
+$ 1/3 B'(s,0,X_1,0)   =  (-2s^2 + 2s)X_1 \approx 2sX_1 $ for $s\rightarrow 0$ \par
+$ 1/3 B'(1-s,0,X_1,0) = (-2s^2 + 2s)X_1 \approx 2sX_1  $ for $s\rightarrow 0$ $\par
+*/
+/* Of course the same should be done for dy and dyin */
+if ( ((number_zero(dx)||number_positive(dx_m)) && number_positive(dy)) &&
+     (number_zero(dxin) && number_positive(dyin)) ){
+     number_clone(dx_m, epsilon_t);
+     number_clone(dxin_m, epsilon_t);
+     if (number_positive(x1)){      
+       set_number_from_addition (dxin, dxin, epsilon_t); 
+       set_number_from_addition (dx, dx, epsilon_t); 
+     } else if (number_negative(x1)) {
+       set_number_from_substraction (dxin, dxin, epsilon_t);  
+       set_number_from_substraction (dx, dx, epsilon_t);  
+     } else if (number_positive(x0)) { 
+       set_number_from_addition (dxin, dxin, epsilon_t); 
+       set_number_from_addition (dx, dx, epsilon_t); 
+     } else if (number_negative(x0)) {
+       set_number_from_substraction (dxin, dxin, epsilon_t);  
+       set_number_from_substraction (dx, dx, epsilon_t);  
+     }
+}
+/* END PATCH ****/
 
 @ The next step is to bracket the initial direction between consecutive
 edges of the pen polygon.  We must be careful to turn clockwise only if
@@ -13737,11 +14018,35 @@
   mp_number ab_vs_cd;
   new_number (ab_vs_cd);
   ab_vs_cd (ab_vs_cd, dy, dxin, dx, dyin);
-  turn_amt = mp_get_turn_amt (mp, w0, dx, dy, number_nonnegative(ab_vs_cd));
+#ifdef DEBUGENVELOPE
+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));
+#endif
+ turn_amt = mp_get_turn_amt (mp, w0, dx, dy, number_nonnegative(ab_vs_cd));
+#ifdef DEBUGENVELOPE
+dbg_dn(turn_amt);
+dbg_close_t;dbg_comma;
+dbg_nl;
+#endif
   free_number (ab_vs_cd);
+#ifdef DEBUGENVELOPE
+dbg_key(w0 before walk);dbg_open_t;dbg_nl;
+dbg_n(w0->x_coord);dbg_n(w0->y_coord);
+dbg_close_t;dbg_comma;
+#endif
   w = mp_pen_walk (mp, w0, turn_amt);
   w0 = w;
+#ifdef DEBUGENVELOPE
+dbg_key(w0 after walk);dbg_open_t;dbg_nl;
+dbg_n(w0->x_coord);dbg_n(w0->y_coord);
+dbg_close_t;dbg_comma;
+dbg_open_t;dbg_in(mp_knot_info(p));
+#endif
   mp_knot_info (p) = mp_knot_info (p) + turn_amt;
+#ifdef DEBUGENVELOPE
+  dbg_in(mp_knot_info(p));dbg_close_t;dbg_comma;
+#endif
 }
 
 @ Decide how many pen offsets to go away from |w| in order to find the offset
@@ -13762,11 +14067,13 @@
   mp_knot ww;   /* a neighbor of knot~|w| */
   integer s;    /* turn amount so far */
   mp_number t;    /* |ab_vs_cd| result */
+  mp_number t_ap;    /* |ab_vs_cd| approx. result */
   mp_number arg1, arg2;
   s = 0;
   new_number (arg1);
   new_number (arg2);
   new_number (t);
+  new_number (t_ap);
   if (ccw) {
     ww = mp_next_knot (w);
     do {
@@ -13773,8 +14080,30 @@
       set_number_from_substraction (arg1, ww->x_coord, w->x_coord);
       set_number_from_substraction (arg2, ww->y_coord, w->y_coord);
       ab_vs_cd (t, dy, arg1, dx, arg2);
-      if (number_negative(t))
+#ifdef DEBUGENVELOPE
+     dbg_sp;
+     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_close_t;dbg_comma;
+     dbg_nl;
+#endif
+      /* BEGIN PATCH */
+           if (number_zero(dx) && number_zero(arg1) && number_positive(dy) && number_positive(arg2)) 
         break;
+      if (number_zero(dx) && number_zero(arg1) && number_negative(dy) && number_negative(arg2)) 
+        break;
+      if (number_zero(dy) && number_zero(arg2) && number_negative(dx) && number_negative(arg1)) 
+        break;
+      if (number_zero(dx) && number_zero(arg1) && number_negative(dy) && number_positive(arg2)) 
+        set_number_to_unity(t);
+      if (number_zero(dy) && number_zero(arg2) && number_positive(dx) && number_negative(arg1)) 
+        set_number_to_unity(t);
+     
+      /* END PATCH */
+      if (number_negative(t)) 
+        break;
       incr (s);
       w = ww;
       ww = mp_next_knot (ww);
@@ -13794,6 +14123,7 @@
     }
   }
   free_number (t);
+  free_number (t_ap);
   free_number (arg1);
   free_number (arg2);
   return s;
@@ -13950,8 +14280,18 @@
 @<Decide on the net change in pen offsets and set |turn_amt|@>=
 {
   mp_number ab_vs_cd;
+  mp_number t_ap;
+  new_number (t_ap);
   new_number (ab_vs_cd);
+#ifdef DEBUGENVELOPE
+dbg_sp;
+dbg_key(Decide on the net change in pen offsets and set turn_amt);dbg_open_t;dbg_nl;
+#endif
   ab_vs_cd (ab_vs_cd, dx, dyin, dxin, dy);
+#ifdef DEBUGENVELOPE
+dbg_n(ab_vs_cd);dbg_n(dx);dbg_n(dyin);dbg_n(dxin);dbg_n(dy);
+dbg_close_t;dbg_comma;dbg_nl;
+#endif
   if (number_negative (ab_vs_cd))
     d_sign = -1;
   else if (number_zero (ab_vs_cd))
@@ -13959,6 +14299,7 @@
   else
     d_sign = 1;
   free_number (ab_vs_cd);
+  free_number (t_ap);
 }
 if (d_sign == 0) {
   @<Check rotation direction based on node position@>
@@ -13978,7 +14319,16 @@
 }
 @<Make |ss| negative if and only if the total change in direction is
   more than $180^\circ$@>;
+#ifdef DEBUGENVELOPE
+dbg_nl;
+dbg_key(mp_get_turn_amt_dxin_dyin);dbg_open_t;dbg_str(--[==[call mp_get_turn_amt]==]);dbg_nl; ;
+dbg_n(w->x_coord);dbg_n(w->y_coord);dbg_n(dxin);dbg_n(dyin);dbg_in((d_sign > 0));
+#endif
 turn_amt = mp_get_turn_amt (mp, w, dxin, dyin, (d_sign > 0));
+#ifdef DEBUGENVELOPE
+dbg_dn(turn_amt);
+dbg_close_t;dbg_nl;dbg_nl;
+#endif
 if (number_negative(ss))
   turn_amt = turn_amt - d_sign * n
 
@@ -14024,6 +14374,10 @@
   new_fraction (r2);
   take_fraction (r1, x0, y2);
   take_fraction (r2, x2, y0);
+#ifdef DEBUGENVELOPE
+dbg_sp;
+dbg_open_t;dbg_dn(d_sign);dbg_close_t;dbg_comma;dbg_nl;
+#endif
   number_half (r1);
   number_half (r2);
   set_number_from_substraction(t0, r1, r2);
@@ -14030,7 +14384,8 @@
   set_number_from_addition (arg1, y0, y2);
   take_fraction (r1, x1, arg1);
   set_number_from_addition (arg1, x0, x2);
-  take_fraction (r1, y1, arg1);
+  /*%take_fraction (r1, y1, arg1);*//* The old one, is it correct ?*/
+  take_fraction (r2, y1, arg1);
   number_half (r1);
   number_half (r2);
   set_number_from_substraction(t1, r1, r2);
@@ -14065,6 +14420,7 @@
 }
 {
   mp_number tmp1, tmp2, r1, r2, arg1;
+  mp_number abs_ss, eps_ss;
   new_fraction (r1);
   new_fraction (r2);
   new_number(arg1);
@@ -14077,6 +14433,28 @@
   set_number_from_addition(arg1, y0, y2);
   take_fraction (r2, arg1, tmp2);
   set_number_from_addition (ss, r1, r2);
+  /* BEGIN PATCH */
+#ifdef DEBUGENVELOPE
+dbg_key(patch ss before);dbg_open_t;dbg_nl;
+dbg_n(ss);
+dbg_close_t;dbg_comma;dbg_nl;
+#endif
+  new_number(abs_ss);
+  new_number(eps_ss);
+  set_number_from_double(eps_ss,1e-6);
+  number_clone(abs_ss,ss);
+  number_abs(abs_ss);
+  if (number_greaterequal(eps_ss,abs_ss)) {
+    set_number_to_zero(ss);/* a warning here ? */
+  }
+#ifdef DEBUGENVELOPE
+dbg_key(patch ss after);dbg_open_t;dbg_nl;
+dbg_n(ss);
+dbg_close_t;dbg_comma;dbg_nl;
+#endif
+  free_number(abs_ss);
+  free_number(eps_ss);
+  /* END PATCH */
   free_number (arg1);
   free_number (r1);
   free_number (r2);
@@ -15915,8 +16293,8 @@
         } else {
           if (number_greaterequal (absv, coef_bound_k) && mp->watch_coefs) {
             mp_type (qq) = independent_needing_fix;
-	    /* If we set this , then we can drop (mp_type(pp) == independent_needing_fix && mp->fix_needed) later */
-	    /* set_number_from_scaled (value_number (qq), indep_value(qq)); */
+	    /* If we set this , then we can drop |(mp_type(pp) == independent_needing_fix && mp->fix_needed)| later */
+	    /* |set_number_from_scaled (value_number (qq), indep_value(qq));| */
             mp->fix_needed = true;
           }
           set_mp_link (r, (mp_node) s);
@@ -16060,8 +16438,8 @@
         } else {
           if (number_greaterequal(test, coef_bound_k) && mp->watch_coefs) {
             mp_type (qq) = independent_needing_fix;
-	    /* If we set this , then we can drop (mp_type(pp) == independent_needing_fix && mp->fix_needed) later */
-	    /* set_number_from_scaled (value_number (qq), indep_value(qq)); */
+	    /* If we set this , then we can drop |(mp_type(pp) == independent_needing_fix && mp->fix_needed)| later */
+	    /* |set_number_from_scaled (value_number (qq), indep_value(qq));| */
             mp->fix_needed = true;
           }
           set_mp_link (r, (mp_node) s);
@@ -24675,7 +25053,7 @@
     {
       mp_number r;
       new_number (r);
-      /*mp_norm_rand (mp, &r);*/
+      /*|mp_norm_rand (mp, &r)|;*/
       m_norm_rand (r);
       mp->cur_exp.type = mp_known;
       set_cur_exp_value_number (r);
@@ -24872,7 +25250,7 @@
         {
           mp_number vvx;
           new_number (vvx);
-          /*mp_unif_rand (mp, &vvx, cur_exp_value_number ());*/
+          /*|mp_unif_rand (mp, &vvx, cur_exp_value_number ());|*/
           m_unif_rand (vvx, cur_exp_value_number ());
           set_cur_exp_value_number (vvx);
           free_number (vvx);

Modified: trunk/Build/source/texk/web2c/mplibdir/mpmathbinary.w
===================================================================
--- trunk/Build/source/texk/web2c/mplibdir/mpmathbinary.w	2016-09-17 01:10:34 UTC (rev 42087)
+++ trunk/Build/source/texk/web2c/mplibdir/mpmathbinary.w	2016-09-17 07:59:22 UTC (rev 42088)
@@ -1100,6 +1100,24 @@
   mpfr_set(b, (mpfr_ptr )b_orig.data.num, ROUNDING);
   mpfr_set(c, (mpfr_ptr )c_orig.data.num, ROUNDING);
   mpfr_set(d, (mpfr_ptr )d_orig.data.num, ROUNDING);
+  
+  mpfr_mul(q,a,b,ROUNDING);
+  mpfr_mul(r,c,d,ROUNDING);
+  cmp = mpfr_cmp(q,r);
+  if (cmp==0) {
+    mpfr_set(ret->data.num, zero, ROUNDING);
+    goto RETURN;
+  }
+  if (cmp>0) {
+    mpfr_set(ret->data.num, one, ROUNDING);
+    goto RETURN;
+  }
+  if (cmp<0) {
+    mpfr_set(ret->data.num, minusone, ROUNDING);
+    goto RETURN;
+  }
+
+  /*TODO: remove this part of the code until RETURN */
   @<Reduce to the case that |a,c>=0|, |b,d>0|@>;
   while (1) {
     mpfr_div(q,a,d, ROUNDING);

Modified: trunk/Build/source/texk/web2c/mplibdir/mpmathdecimal.w
===================================================================
--- trunk/Build/source/texk/web2c/mplibdir/mpmathdecimal.w	2016-09-17 01:10:34 UTC (rev 42087)
+++ trunk/Build/source/texk/web2c/mplibdir/mpmathdecimal.w	2016-09-17 07:59:22 UTC (rev 42088)
@@ -1213,11 +1213,21 @@
 void mp_ab_vs_cd (MP mp, mp_number *ret, mp_number a_orig, mp_number b_orig, mp_number c_orig, mp_number d_orig) {
   decNumber q, r, test; /* temporary registers */
   decNumber a, b, c, d;
+  decNumber ab, cd;
   (void)mp;
   decNumberCopy(&a, (decNumber *)a_orig.data.num);
   decNumberCopy(&b, (decNumber *)b_orig.data.num);
   decNumberCopy(&c, (decNumber *)c_orig.data.num);
   decNumberCopy(&d, (decNumber *)d_orig.data.num);
+
+  decNumberMultiply (&ab, (decNumber *)a_orig.data.num, (decNumber *)b_orig.data.num, &set);
+  decNumberMultiply (&cd, (decNumber *)c_orig.data.num, (decNumber *)d_orig.data.num, &set);
+  decNumberCompare(ret->data.num, &ab, &cd, &set);
+  mp_check_decNumber(mp, ret->data.num, &set);
+  if (1>0) 
+    return;
+
+
   @<Reduce to the case that |a,c>=0|, |b,d>0|@>;
   while (1) {
     decNumberDivide(&q,&a,&d, &set);
@@ -1699,13 +1709,13 @@
 @c
 void mp_decimal_sin_cos (MP mp, mp_number z_orig, mp_number *n_cos, mp_number *n_sin) {
   decNumber rad;
+  double tmp;
   decNumber one_eighty;
-  decNumberFromInt32(&one_eighty, 180 * 16);
+  tmp = mp_number_to_double(z_orig)/16.0;
+  
 #if DEBUG
   fprintf(stdout, "\nsin_cos(%f)", mp_number_to_double(z_orig));
 #endif
-  decNumberMultiply(&rad, z_orig.data.num, &PI_decNumber, &set);
-  decNumberDivide(&rad, &rad, &one_eighty, &set);
 #if 0
   if (decNumberIsNegative(&rad)) {
     while (decNumberLess(&rad,&PI_decNumber))
@@ -1715,9 +1725,23 @@
       decNumberSubtract(&rad, &rad, &PI_decNumber, &set);
   }
 #endif
-  sinecosine(&rad, n_sin->data.num, n_cos->data.num); 
-  decNumberMultiply(n_cos->data.num,n_cos->data.num,&fraction_multiplier_decNumber, &set);
-  decNumberMultiply(n_sin->data.num,n_sin->data.num,&fraction_multiplier_decNumber, &set);
+    if ((tmp == 90.0)||(tmp == -270)){
+    decNumberZero(n_cos->data.num);
+    decNumberCopy(n_sin->data.num,&fraction_multiplier_decNumber);
+  } else if ((tmp == -90.0)||(tmp == 270.0)) {
+    decNumberZero(n_cos->data.num);
+    decNumberCopyNegate(n_sin->data.num,&fraction_multiplier_decNumber);
+  } else if ((tmp == 180.0) || (tmp == -180.0)) {
+    decNumberCopyNegate(n_cos->data.num,&fraction_multiplier_decNumber);
+    decNumberZero(n_sin->data.num);
+  } else {
+   decNumberFromInt32(&one_eighty, 180 * 16);
+   decNumberMultiply(&rad, z_orig.data.num, &PI_decNumber, &set);
+   decNumberDivide(&rad, &rad, &one_eighty, &set);
+   sinecosine(&rad, n_sin->data.num, n_cos->data.num); 
+   decNumberMultiply(n_cos->data.num,n_cos->data.num,&fraction_multiplier_decNumber, &set);
+   decNumberMultiply(n_sin->data.num,n_sin->data.num,&fraction_multiplier_decNumber, &set);
+  }
 #if DEBUG
   fprintf(stdout, "\nsin_cos(%f,%f,%f)", decNumberToDouble(&rad),
 mp_number_to_double(*n_cos), mp_number_to_double(*n_sin));

Modified: trunk/Build/source/texk/web2c/mplibdir/mpmathdouble.w
===================================================================
--- trunk/Build/source/texk/web2c/mplibdir/mpmathdouble.w	2016-09-17 01:10:34 UTC (rev 42087)
+++ trunk/Build/source/texk/web2c/mplibdir/mpmathdouble.w	2016-09-17 07:59:22 UTC (rev 42088)
@@ -1,4 +1,4 @@
-% $Id: mpmathdouble.w 2070 2015-10-06 10:35:23Z luigi $
+% $Id: mpmathdouble.w 2091 2016-09-16 23:07:58Z luigi $
 %
 % This file is part of MetaPost;
 % the MetaPost program is in the public domain.
@@ -814,6 +814,11 @@
   integer q, r; /* temporary registers */
   integer a, b, c, d;
   (void)mp;
+  
+  mp_double_ab_vs_cd(mp,ret, a_orig, b_orig, c_orig, d_orig);
+  if (1>0) 
+    return ;
+  /* TODO: remove this code until the end */
   a = a_orig.data.dval;
   b = b_orig.data.dval;
   c = c_orig.data.dval;
@@ -1208,9 +1213,21 @@
 @c
 void mp_double_sin_cos (MP mp, mp_number z_orig, mp_number *n_cos, mp_number *n_sin) {
   double rad;
-  rad = (z_orig.data.dval / angle_multiplier) * PI/180.0;
-  n_cos->data.dval = cos(rad) * fraction_multiplier;
-  n_sin->data.dval = sin(rad) * fraction_multiplier;
+  rad = (z_orig.data.dval / angle_multiplier); /* still degrees */
+  if ((rad == 90.0)||(rad == -270)){
+    n_cos->data.dval = 0.0;
+    n_sin->data.dval = fraction_multiplier;
+  } else if ((rad == -90.0)||(rad == 270.0)) {
+    n_cos->data.dval = 0.0;
+    n_sin->data.dval = -fraction_multiplier;
+  } else if ((rad == 180.0) || (rad == -180.0)) {
+    n_cos->data.dval = -fraction_multiplier;
+    n_sin->data.dval = 0.0;
+  } else {
+    rad = rad * PI/180.0;
+    n_cos->data.dval = cos(rad) * fraction_multiplier;
+    n_sin->data.dval = sin(rad) * fraction_multiplier;
+  }
 #if DEBUG
   fprintf(stdout, "\nsin_cos(%f,%f,%f)", mp_number_to_double(z_orig),
 mp_number_to_double(*n_cos), mp_number_to_double(*n_sin));



More information about the tex-live-commits mailing list