[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: MF hackery (arrow kit)



Ulrik, I have applied your patches to ymearr.mf and added some more.
The diff below is against pristine 0.54. 

> Remaining problems:
> 
> * The construction of zero-width characters is different from
>   that of Knuth's mapstochar.  Instead of directly specifying
>   a width of 0pt#, he first used a non-zero width, followed 
>   by |adjust_fit(0,0)| and a call to |zero_width|.  Is there
>   any difference other than correctly setting the width of the
>   proof-sheet box?  The problem is that calling |adjust_fit(0,0)|
>   after specifying a width of 0pt# gives a division-by-zero error.

I have tried |zero_width|, but that did not correctly center the 
glyph. Now I use an explicit |adjust_fit| to cancel the width.


> * The gaped squiggly arrows produce some stray pixes within the 
>   are that should be erased.  Anyone knows how to fix this???

Instead of |unfill|ing a box, I now calculate the intersection point
and draw a shorter spline. This eliminates the stray pixels and gives
correctly rounded endings.

> * There are still a few remaining inconsistencies as to when 
>   points are positioned at hround(w-u) or hround(w-u-eps), etc.

I have ignored these for now.

> * I haven't yet tested if the dot separation of dashed arrowheads
>   and arrow extension pieces fits smoothly.  With 8 dots per 12u#
>   the dot separation would be 1.5u# and the first dot would have 
>   to be positioned at 0.5dot_sep (or 0.75u#) from the edges of 
>   the character box.  I hope this will be satisfied in all cases.

This turned out to be a bit tricky. We cannot guarantee uniform
spacing between the dots without sacrificing device-independence,
so I increased the space between the dots a bit, making the 
nonuniformity much less prominent. This is only a problem for
low resolutions, it was quite noticeable at 300dpi, but invisible
at 900dpi.

> * I haven't yet checked if all the arrows (apparently assembled
>   from various sources) follow the design principles of Knuth's
>   latest sources or if some of them are still based on old CM.

I haven't done anything about this.

> * It is unclear to me why there is an |italcorr| specification
>   for some of the arrow extension pieces.  I presume this would
>   be totally unecessary in an unslanted symbol font anyway.

All |italcorr| statements have been removed.

> P.P.S.  Another one: The CM square brackets from punct.mf have 
> a width of 5u# (and relatively little side-bearings), while the
> floor/ceiling bracktes from symbol.mf have a width of 8u# (with 
> wider side-bearings and rounded corners at the end of strokes).
> Now the big square brackets have a width of 6u, 6.5u, 7u, 7.5u,
> while the big floor/ceilings have a width of 7u, 7.5u, 8u, 8.5u,
> and both of the share the same set of extensible modules.
>
> Would it seem reasonable that all of them should have consistent
> widths or is there a good design reason why floors/ceilings are
> a little wider?  I suppose that even if we consider this a bug, 
> we will have to keep the old widths for metrics compatibility
> in the CM implementation, although it might also be interesting 
> to provide an alternative optimized version as well.  Opions?

I was surprised by the difference between the mf programs for the
brackets and floors in punct.mf and symbol.mf. While the brackets 
are very sophisticated, the floors are almost trivial. Is this
because the brackets are designed for text fonts, while the floors
are not ?

Regards, Matthias



--- ORIG/ymearr.mf	Sat Nov  1 14:07:03 1997
+++ ./ymearr.mf	Sat Nov  1 12:58:10 1997
@@ -1,10 +1,21 @@
+% experimental changes (UV, 31.10.97):
+%
+% arrow_ext_width#:=12u#;	(was: 14u#)
+% 3/2arrow_ext_width#:=18u#;	(was: 4/3x, 18.66u#)
+%
+% more experimental changes (MC, 1.11.97)
+%
+% changed dot_sep to 1/6 arrow_ext_width
+% made squiggly negation steeper
+% made squiggly pieces shoot over a bit.
 
-arrow_ratio:=14/9;
-arrow_ext_width#:=14u#;
+
+arrow_ext_width#:=12u#;
 arrow_head_width#:=9u#;
+dot_sep#:=arrow_ext_width#/6;
 arrow_overshoot:=u-eps;
 
-define_pixels(arrow_ext_width,arrow_head_width); 
+define_pixels(arrow_ext_width,arrow_head_width,dot_sep); 
 
 def single_height = v_center(spread#+rule_thickness#) enddef;
 def double_height = v_center(spread#+.48asc_height#) enddef;
@@ -25,29 +36,30 @@
   ...z5{z6-z4}...z6{up}...z7{z8-z6}...cycle;  % circle and interior
 enddef;
 
-% 8 control glyphs 
+% 8 control glyphs
 
-cmchar "Single left end"; 
+cmchar "Single left arrow end"; 
 compute_spread(.45x_height#,.55x_height#); 
 beginchar(slot_NONE,arrow_head_width#,single_height); 
 adjust_fit(0,0); pickup rule.nib;
-y0=y1=math_axis; x1=hround(w+arrow_overshoot); lft x0=hround u;
-draw z0--z1; endchar;
+lft x1=hround u; x2=hround(w+arrow_overshoot);
+y1=y2=math_axis;
+draw z1--z2;
+penlabels(1,2); endchar;
 
 cmchar "Single arrow extension";
 compute_spread(.45x_height#,.55x_height#);
 beginchar(slot_singleext,arrow_ext_width#,single_height); 
-pickup rule.nib;
-lft x1=hround(0-arrow_overshoot); 
-x2=w-x1; 
+adjust_fit(0,0); pickup rule.nib;
+x1=hround(0-arrow_overshoot); x2=w-x1; 
 y1=y2=math_axis;
 draw z1--z2;  % bar
-labels(1,2); endchar;
+penlabels(1,2); endchar;
 
 cmchar "Single arrow negation";
 compute_spread(.45x_height#,.55x_height#);
-beginchar(slot_NEG,0pt#,single_height); 
-pickup rule.nib;
+beginchar(slot_NEG,4u#,single_height); 
+adjust_fit(-(2u#+letter_fit#),-(2u#+letter_fit#)); pickup rule.nib;
 y1=math_axis;
 y3-y1=.24asc_height+eps;
 char_center(100); top y101=top y3; x101=x100+2u;
@@ -57,55 +69,51 @@
 cmchar "Single arrow negated extension";
 compute_spread(.45x_height#,.55x_height#);
 beginchar(slot_NEGEXT,arrow_ext_width#,single_height); 
-pickup rule.nib;
-lft x1=hround 0 - arrow_overshoot; x2=w-x1; y1=y2=math_axis;
+adjust_fit(0,0); pickup rule.nib;
+x1=hround(0-arrow_overshoot); x2=w-x1;
+y1=y2=math_axis;
 draw z1--z2;  % bar
 y3-y1=.24asc_height+eps;
 char_center(100); top y101=top y3; x101=x100+2u;
 char_negate(100,101,102);
-labels(1,2); endchar;
-
-cmchar "Single gap";
-compute_spread(.45x_height#,.55x_height#);
-beginchar(slot_GAP,arrow_ext_width#/3,single_height); 
-endchar;
+penlabels(1,2); endchar;
 
 cmchar "Single arrow gaped extension";
 compute_spread(.45x_height#,.55x_height#);
-beginchar(slot_GAPEXT,4/3arrow_ext_width#,single_height); 
-pickup rule.nib;
-lft x1=hround(0-arrow_overshoot); 
+beginchar(slot_GAPEXT,3/2arrow_ext_width#,single_height); 
+adjust_fit(0,0); pickup rule.nib;
+x1=hround(0-arrow_overshoot); x4=w-x1;
 x2=hround (3/8w); 
 x3=hround (5/8w);
-x4=w-x1;
 y1=y2=y3=y4=math_axis;
 draw z1--z2;  % bar
 draw z3--z4;
-labels(1,2,3,4); endchar; 
+penlabels(1,2,3,4); endchar; 
 
 cmchar "Squiggly arrow extension";
 compute_spread(.45x_height#,.55x_height#);
 beginchar(slot_SQUIG,arrow_ext_width#,single_height); 
-adjust_fit(0,0); 
+adjust_fit(0,0); pickup rule.nib;
 y2=y4; y1=y3=y5; y3-y4=.24asc_height+eps;
 .5[y3,y4]=math_axis;
 x2-x1=x3-x2=x4-x3=x5-x4;
 x1=0; x5=w;
+x0=x1-o;x6=x5+o;
+y0=y1; y6=y5;
 pickup pencircle scaled rule_thickness; 
-draw z1{right}..z2{right}..z3{right}..z4{right}..{right}z5; 
-endchar;
+draw z0..z1{right}..z2{right}..z3{right}..z4{right}..{right}z5..z6; 
+penlabels(1,2,3,4,5); endchar;
 
-cmchar "Single arrow dashed extension";
+cmchar "Single dashed arrow extension";
 compute_spread(.45x_height#,.55x_height#);
 beginchar(slot_DASH,arrow_ext_width#,single_height); 
-pickup rule.nib;
-numeric dot_sep; dot_sep:=w/8;
-x0=0;
-y0=y1=y2=y3=y4=y5=y6=y7=y8=math_axis;
-2(x1-x0)=x2-x1=x3-x2=x4-x3=x5-x4=x6-x5=x7-x6=x8-x7=dot_sep;
-drawdot z1; drawdot z2; drawdot z3; drawdot z4;
-drawdot z5; drawdot z6; drawdot z7; drawdot z8;
-labels(0,1,2,3,4,5,6,7,8); endchar;
+adjust_fit(0,0); pickup rule.nib;
+x0=0; y0=math_axis;
+2(x1-x0)=dot_sep; y1=y0; drawdot z1; 
+for j=2 thru 8:
+  x[j]-x[j-1]=dot_sep;  y[j]=y[j-1]; drawdot z[j];
+endfor
+penlabels(range 0 thru 8); endchar;
 
 % 24 left heads
 
@@ -115,7 +123,8 @@
 adjust_fit(0,0); pickup crisp.nib;
 pos1(rule_thickness,90); pos2(rule_thickness,90);
 pos3(rule_thickness,0); pos4(rule_thickness,0);
-y0=y1=y2=math_axis; x1=hround(w); lft x0=hround u;
+y0=y1=y2=math_axis;
+lft x0=hround u; x1=hround(w+arrow_overshoot); 
 y3-y0=y0-y4=if monospace:.24 else:.36 fi asc_height+eps;
 x3=x4=x0+if monospace:3u else:4u fi+eps;
 pos5(rule_thickness,angle(z4-z0)); z5l=z0;
@@ -132,10 +141,11 @@
 compute_spread(.45x_height#,.55x_height#);
 beginchar(slot_Head,arrow_head_width#,double_height);
 adjust_fit(0,0); pickup rule.nib;
-lft x7=hround u-eps; x8=x7; x1=x2=w+arrow_overshoot;
+lft x7=hround u-eps; x8=x7; x1=x2=hround(w+arrow_overshoot);
 y1=y7; y2=y8; y1-y2=spread; .5[y1,y2]=math_axis;
 draw z1--z7; draw z2--z8;  % bars
-pickup crisp.nib; lft x0=hround u-eps; y0=good.y math_axis;
+pickup crisp.nib;
+lft x0=hround u-eps; y0=good.y math_axis;
 pos3(rule_thickness,0); pos4(rule_thickness,0);
 y3-y1=y2-y4=.24asc_height+eps; x3=x4=x0+6u+eps;
 pos5(rule_thickness,angle(z4-z0)); z5l=z0;
@@ -152,34 +162,36 @@
 cmchar "Triple left arrow head"; 
 compute_spread(.45x_height#,.55x_height#); 
 beginchar(slot_HEAD,arrow_head_width#,triple_height); 
-adjust_fit(0,0); pickup rule.nib; penpos1(rule_thickness,90); 
-penpos2(rule_thickness,90); penpos3(1.5bar,0); penpos4(1.5bar,0); 
+adjust_fit(0,0); pickup crisp.nib;
+pos1(rule_thickness,90); pos2(rule_thickness,90);
+pos3(rule_thickness,0); pos4(rule_thickness,0); 
 y0=y1=y2=math_axis; x1=hround(w+arrow_overshoot); 
-lft x0=hround u; x0'=x0''=x0; x1'=x1''=x1; 
-y1'=y1+spread;y1''=y1-spread; y0'=y1'; y0''=y1''; draw 
-z0'--z1'; draw z0''--z1''; % draw bars  
+lft x0=hround u-eps; x0'=x0''=x0; x1'=x1''=x1; 
+y1'-y1=y1-y1''=spread; y0'=y1'; y0''=y1'';
+pickup rule.nib;  
+draw z0'--z1'; draw z0''--z1''; % draw bars  
 pickup crisp.nib;  
 y3-y0'=y0''-y4=.24asc_height+eps; x3=x4=x0+6u+eps; 
-pos5(bar,angle(z4-z0)); z5l=z0; pos6(bar,angle(z3-z0)); 
-z6l=z0; z9=.381966[.5[z3,z4],z0]; erase filldraw 
-z0..{z3-z9}z3--(0,y3) 
- --(0,y4)--z4{z9-z4}..z0& cycle; numeric t; path p; 
-p=z4r{z9-z4}..z6r; t=xpart(p 
-intersectiontimes((0,y2l)--(w,y2l))); x2=xpart point t of p; 
+pos5(rule_thickness,angle(z4-z0)); z5l=z0;
+pos6(rule_thickness,angle(z3-z0)); z6l=z0;
+z9=.381966[.5[z3,z4],z0];
+erase filldraw z0..{z3-z9}z3--(0,y3) 
+ --(0,y4)--z4{z9-z4}..z0& cycle;
+numeric t; path p; p=z4r{z9-z4}..z6r;
+t=xpart(p intersectiontimes((0,y2l)--(w,y2l))); x2=xpart point t of p; 
 pickup rule.nib; draw z2--z1; pickup crisp.nib;  
 filldraw z0..{z4-z9}z4l--subpath (0,t) of\\(z4r{z9-z4}..z6r)
-%--z2l---z1l..z1r---z2r
---subpath (t,0) of\\(z3r{z9-z3}..z5r) 
+ --subpath (t,0) of\\(z3r{z9-z3}..z5r) 
  --z3l{z9-z3}..z0 & cycle;  % arrowhead and stem 
 penlabels(0,1,2,3,4,5,6,9,0',0'',1',1''); endchar; 
 
 cmchar "Thick left arrow head";
 beginchar(slot_thickhead,arrow_head_width#,single_height); 
-pickup rule.nib;
+adjust_fit(0,0); pickup rule.nib;
 penpos1(.25rule_thickness,90); penpos2(.25rule_thickness,90); penpos3(bar,0); 
 penpos4(bar,0);
 y0=y1=y2=math_axis; x0=hround 1.5u-eps;
-rt x1=w-(hround 0-arrow_overshoot);
+x1=(hround w+arrow_overshoot);
 y3-y0=y0-y4=.24asc_height+eps; x3=x4=x0+3u+eps;
 penpos5(bar,angle(z4-z0)); z5l=z0; penpos6(bar,angle(z3-z0)); z6l=z0;
 z9=.381966[.5[z3,z4],z0];
@@ -196,17 +208,13 @@
 adjust_fit(0,0); pickup crisp.nib;  
 pos1(rule_thickness,90); pos2(rule_thickness,90); 
 pos3(bar,0); pos4(bar,0); y0=y1=y2=math_axis; 
-x1=hround(w+arrow_overshoot); % x1+.5rule_thickness=hround(w-u); 
-lft x0=hround u; 
+x1=hround(w+arrow_overshoot); lft x0=hround u; 
 y3-y0=y0-y4=.24asc_height+eps; x3=x4=x0+3u+eps; 
 pos5(bar,angle(z4-z0)); z5l=z0; pos6(bar,angle(z3-z0)); 
 z6l=z0; z9=.381966[.5[z3,z4],z0];  
-numeric t; path p;  
-p=z4r{z9-z4}..z6r;  
-t=xpart(p intersectiontimes((0,y2l)--(w,y2l)));  
-x2=xpart point t of p;  
-path p; p=z0..{z4-z9}z4l--subpath (0,t) 
-of\\(z4r{z9-z4}..z6r) 
+numeric t; path p;  p=z4r{z9-z4}..z6r;
+t=xpart(p intersectiontimes((0,y2l)--(w,y2l))); x2=xpart point t of p;
+path p; p=z0..{z4-z9}z4l--subpath (0,t) of\\(z4r{z9-z4}..z6r) 
  --z2l--z2r--subpath (t,0) of\\(z3r{z9-z3}..z5r) 
  --z3l{z9-z3}..z0 & cycle; % second arrowhead 
 filldraw z0..{z4-z9}z4l--subpath (0,t) of\\(z4r{z9-z4}..z6r) 
@@ -223,7 +231,7 @@
 y1=y2=math_axis; y1-y3=y4-y1=.24asc_height+eps;
 draw z3--z4;  % stem
 draw z1--z2;  % bar stub
-labels(1,2,3,4); endchar;
+penlabels(1,2,3,4); endchar;
 
 cmchar "Double left mapsto arrow head";
 compute_spread(.45x_height#,.55x_height#);
@@ -235,7 +243,7 @@
 draw z3--z4;  % stem
 draw z1--z2;  % bar stub
 draw z5--z6;  % bar stub
-labels(1,2,3,4,5,6); endchar;
+penlabels(1,2,3,4,5,6); endchar;
 
 cmchar "Triple left mapsto arrow head";
 compute_spread(.45x_height#,.55x_height#);
@@ -248,7 +256,7 @@
 draw z1--z2;  % bar stub
 draw z5--z6;  % bar stub
 draw z7--z8;  % bar stub
-labels(1,2,3,4,5,6,7,8); endchar;
+penlabels(1,2,3,4,5,6,7,8); endchar;
 
 cmchar "Left hook up";
 compute_spread(.45x_height#,.55x_height#);
@@ -258,7 +266,7 @@
 y1-y3=spread; y2=.5[y1,y3]; y3=math_axis=y4;
 x4=hround(w+arrow_overshoot);
 draw z1{left}...z2{down}...z3{right}---z4;  % hook
-labels(1,2,3); endchar;
+penlabels(1,2,3,4); endchar;
 
 cmchar "Left hook down";
 compute_spread(.45x_height#,.55x_height#);
@@ -268,7 +276,7 @@
 y3-y1=spread; y2=.5[y1,y3]; y3=math_axis=y4;
 x4=hround(w+arrow_overshoot);
 draw z1{left}...z2{up}...z3{right}---z4;  % hook
-labels(1,2,3); endchar;
+penlabels(1,2,3,4); endchar;
 
 % 146: Left harpoon up
 % 147: Left harpoon down
@@ -313,7 +321,8 @@
 adjust_fit(0,0); pickup crisp.nib;
 pos1(rule_thickness,90); pos2(rule_thickness,90);
 pos3(rule_thickness,0); pos4(rule_thickness,0);
-y0=y1=y2=math_axis; x1=hround (0); rt x0=hround(w-u);
+y0=y1=y2=math_axis; 
+rt x0=hround(w-u); x1=hround(0-arrow_overshoot); 
 y3-y0=y0-y4=if monospace:.24 else:.36 fi asc_height+eps;
 x3=x4=x0-if monospace:3u else:4u fi-eps;
 pos5(rule_thickness,angle(z4-z0)); z5l=z0;
@@ -330,10 +339,11 @@
 compute_spread(.45x_height#,.55x_height#);
 beginchar(slot_Headright,arrow_head_width#,double_height);
 adjust_fit(0,0); pickup rule.nib;
-lft x1=hround 0 - arrow_overshoot; x2=x1; x7=x8=w-hround u-eps;
+x1=x2=hround(0-arrow_overshoot); rt x7=w-hround u-eps; x8=x7;
 y1=y7; y2=y8; y1-y2=spread; .5[y1,y2]=math_axis;
 draw z1--z7; draw z2--z8;  % bars
-pickup crisp.nib; rt x0=hround(w-u)+eps; y0=good.y math_axis;
+pickup crisp.nib;
+rt x0=hround(w-u)+eps; y0=good.y math_axis;
 pos3(rule_thickness,0); pos4(rule_thickness,0);
 y3-y1=y2-y4=.24asc_height+eps; x3=x4=x0-6u-eps;
 pos5(rule_thickness,angle(z4-z0)); z5l=z0;
@@ -350,35 +360,37 @@
 cmchar "Triple right arrow head"; 
 compute_spread(.45x_height#,.55x_height#); 
 beginchar(slot_HEADright,arrow_head_width#,triple_height); 
-adjust_fit(0,0); pickup rule.nib; penpos1(rule_thickness,90); 
-penpos2(rule_thickness,90); penpos3(1.5bar,0); penpos4(1.5bar,0); 
+adjust_fit(0,0); pickup crisp.nib;
+pos1(rule_thickness,90); pos2(rule_thickness,90);
+pos3(rule_thickness,0); pos4(rule_thickness,0); 
 y0=y1=y2=math_axis; x1=hround(0-arrow_overshoot);  
-rt x0=hround (w-u); x0'=x0''=x0; x1'=x1''=x1; 
-y1'=y1+spread;y1''=y1-spread; y0'=y1'; y0''=y1''; 
+rt x0=hround(w-u)+eps; x0'=x0''=x0; x1'=x1''=x1; 
+y1'-y1=y1-y1''=spread; y0'=y1'; y0''=y1''; 
+pickup rule.nib;  
 draw z0'--z1'; draw z0''--z1''; % draw bars  
 pickup crisp.nib;  
 y3-y0'=y0''-y4=.24asc_height+eps; x3=x4=x0-6u-eps; 
-penpos5(bar,angle(z0-z4)); z5r=z0; penpos6(bar,angle(z0-z3)); 
-z6r=z0; z9=.381966[.5[z3,z4],z0]; erase filldraw 
-z0..{z3-z9}z3--(w,y3)--(w,y4)--z4{z9-z4}..z0& cycle; 
-numeric t; path p; 
-p=z4l{z9-z4}..z6l; t=xpart(p intersectiontimes((0,y2l)--(w,y2l))); 
-x2=xpart point t of p; 
+pos5(rule_thickness,angle(z0-z4)); z5r=z0;
+pos6(rule_thickness,angle(z0-z3)); z6r=z0;
+z9=.381966[.5[z3,z4],z0];
+erase filldraw z0..{z3-z9}z3--(w,y3)
+ --(w,y4)--z4{z9-z4}..z0& cycle; 
+ numeric t; path p; p=z4l{z9-z4}..z6l;
+ t=xpart(p intersectiontimes((0,y2l)--(w,y2l))); x2=xpart point t of p; 
 pickup rule.nib; draw z2--z1; pickup crisp.nib;  
 filldraw z0..{z4-z9}z4r--subpath (0,t) of\\(z4l{z9-z4}..z6l) 
-% --z2l---z1l..z1r---z2r
---subpath (t,0) of\\(z3l{z9-z3}..z5l) 
+ --subpath (t,0) of\\(z3l{z9-z3}..z5l) 
  --z3r{z9-z3}..z0 & cycle;  % arrowhead and stem 
 penlabels(0,1,2,3,4,5,6,9,0',0'',1',1''); endchar; 
 
 cmchar "Thick right arrow head";
 beginchar(slot_thickheadright,arrow_head_width#,single_height); 
-pickup rule.nib;
+adjust_fit(0,0); pickup rule.nib;
 penpos1(.25rule_thickness,90); penpos2(.25rule_thickness,90); penpos3(bar,0); 
 penpos4(bar,0);
 y0=y1=y2=math_axis; 
-x1=hround 0 - arrow_overshoot;
-rt x0=w-(hround 1.5u-eps);
+x1=hround(0-arrow_overshoot);
+x0=w-(hround 1.5u-eps);
 y3-y0=y0-y4=.24asc_height+eps; x3=x4=x0-3u-eps;
 penpos5(bar,angle(z4-z0)); z5l=z0; penpos6(bar,angle(z3-z0)); z6l=z0;
 z9=.381966[.5[z3,z4],z0];
@@ -392,16 +404,18 @@
 cmchar "Right double arrow head"; 
 compute_spread(.45x_height#,.55x_height#); 
 beginchar(slot_doubleheadright,arrow_head_width#,single_height); 
-adjust_fit(0,0); 
-pickup crisp.nib;  pos1(rule_thickness,90); pos2(rule_thickness,90); 
-pos3(bar,0); pos4(bar,0);  y0=y1=y2=math_axis; x1=hround(0-arrow_overshoot); 
-rt x0=hround(w-u); y3-y0=y0-y4=.24asc_height+eps; x3=x4=x0-3u-eps; 
+adjust_fit(0,0); pickup crisp.nib;
+pos1(rule_thickness,90); pos2(rule_thickness,90); 
+pos3(bar,0); pos4(bar,0);  y0=y1=y2=math_axis;
+x1=hround(0-arrow_overshoot); rt x0=hround(w-u);
+y3-y0=y0-y4=.24asc_height+eps; x3=x4=x0-3u-eps; 
 pos5(bar,angle(z4-z0)); z5l=z0; pos6(bar,angle(z3-z0)); z6l=z0; 
-z9=.381966[.5[z3,z4],z0]; numeric t; path p; p=z4l{z9-z4}..z6r;  t=xpart(p 
-intersectiontimes((0,y2l)--(w,y2l)));  x2=xpart point t of p;  path p; 
-p=z0..{z4-z9}z4r--subpath (0,t) of\\(z4l{z9-z4}..z6r) 
+z9=.381966[.5[z3,z4],z0];
+numeric t; path p; p=z4l{z9-z4}..z6r;
+t=xpart(p intersectiontimes((0,y2l)--(w,y2l)));  x2=xpart point t of p;
+path p; p=z0..{z4-z9}z4r--subpath (0,t) of\\(z4l{z9-z4}..z6r) 
  --z2l--z2r--subpath (t,0) of\\(z3l{z9-z3}..z5r) 
- --z3r{z9-z3}..z0 & cycle; 
+ --z3r{z9-z3}..z0 & cycle; % second arrowhead  
 filldraw z0..{z4-z9}z4r--subpath (0,t) of\\(z4l{z9-z4}..z6r) 
  --z2l---z1l..z1r---z2r--subpath (t,0) of\\(z3l{z9-z3}..z5r) 
  --z3r{z9-z3}..z0 & cycle;  % arrowhead and stem 
@@ -412,37 +426,36 @@
 compute_spread(.45x_height#,.55x_height#);
 beginchar(slot_mapsfromright,arrow_head_width#,single_height);
 adjust_fit(0,0); pickup rule.nib;
-lft x1=hround(w-u); x2=hround(-arrow_overshoot); x3=x4=x1;
+rt x1=hround(w-u); x2=hround(-arrow_overshoot); x3=x4=x1;
 y1=y2=math_axis; y1-y3=y4-y1=.24asc_height+eps;
 draw z3--z4;  % stem
 draw z1--z2;  % bar stub
-labels(1,2,3,4); endchar;
-
+penlabels(1,2,3,4); endchar;
 
-cmchar "Double right mapsto ";
+cmchar "Double right mapsto";
 compute_spread(.45x_height#,.55x_height#);
 beginchar(slot_Mapsfromright,arrow_head_width#,double_height);
 adjust_fit(0,0); pickup rule.nib;
-lft x1=hround(w-u); x6=x2=hround(-arrow_overshoot); x5=x3=x4=x1;
+rt x1=hround(w-u); x6=x2=hround(-arrow_overshoot); x5=x3=x4=x1;
 y1=y2; y5=y6; .5[y1,y5]=math_axis; y5-y1=spread; 
 y1-y3=y4-y5=.24asc_height+eps;
 draw z3--z4;  % stem
 draw z1--z2;  % bar stub
 draw z5--z6;  % bar stub
-labels(1,2,3,4,5,6); endchar;
+penlabels(1,2,3,4,5,6); endchar;
 
 cmchar "Triple right mapsto";
 compute_spread(.45x_height#,.55x_height#);
 beginchar(slot_MAPSfromright,arrow_head_width#,triple_height);
 adjust_fit(0,0); pickup rule.nib;
-lft x1=hround(w-u); x6=x8=x2=hround(-arrow_overshoot); x5=x7=x3=x4=x1;
+rt x1=hround(w-u); x6=x8=x2=hround(-arrow_overshoot); x5=x7=x3=x4=x1;
 y1=y2=math_axis; y5=y6; y7=y8; y5-y2=y1-y7=spread;
 y3-y5=y7-y4=.24asc_height+eps;
 draw z3--z4;  % stem
 draw z1--z2;  % bar stub
 draw z5--z6;  % bar stub
 draw z7--z8;  % bar stub
-labels(1,2,3,4,5,6,7,8); endchar;
+penlabels(1,2,3,4,5,6,7,8); endchar;
 
 % 168: Right hook up
 % 169: Right hook down
@@ -483,7 +496,7 @@
 
 % 4 special left heads
 
-cmchar "Left squiggly arrow head";
+cmchar "Squiggly left arrow head";
 compute_spread(.45x_height#,.55x_height#);
 beginchar(slot_squighead,arrow_head_width#,single_height);
 adjust_fit(0,0); pickup crisp.nib;
@@ -500,12 +513,11 @@
 filldraw z0..{z4-z9}z4l--subpath (0,t) of\\(z4r{z9-z4}..z6r)
  --z2l---z1l..z1r---z2r--subpath (t,0) of\\(z3r{z9-z3}..z5r)
  --z3l{z9-z3}..z0 & cycle;  % arrowhead and stem
-
 x10=w; y10=math_axis+.12asc_height+eps;
-pickup pencircle scaled rule_thickness; 
-draw z1{right}..z10{right}; 
-
-penlabels(0,1,2,3,4,5,6,9); endchar;
+x11=x10+o; y11=y10;
+pickup rule.nib;
+draw z1{right}..z10{right}..z11; 
+penlabels(0,1,2,3,4,5,6,9,10); endchar;
 
 cmchar "Single left dashed arrow head";
 compute_spread(.45x_height#,.55x_height#);
@@ -525,28 +537,27 @@
  --z2l---z1l..z1r---z2r--subpath (t,0) of\\(z3r{z9-z3}..z5r)
  --z3l{z9-z3}..z0 & cycle;  % arrowhead and stem
 pickup rule.nib;
-numeric dot_sep; dot_sep:=w/8*arrow_ratio;
-y13=y12=y11=y10=y9; x10=hround(w-.5dot_sep);
-x11-x12=x12-x13=x10-x11=dot_sep;
+y13=y12=y11=y10=y0; x10=w-.5dot_sep;
+x12-x13=x11-x12=x10-x11=dot_sep;
 drawdot z10; drawdot z11; drawdot z12; drawdot z13;
-penlabels(0,1,2,3,4,5,6,9,10,11,12,13,14); endchar;
+penlabels(0,1,2,3,4,5,6,9,10,11,12,13); endchar;
 
 cmchar "Double left dashed arrow head";
 compute_spread(.45x_height#,.55x_height#);
 beginchar(slot_Dashhead,arrow_head_width#,double_height);
 adjust_fit(0,0); pickup rule.nib;
-lft x7=hround u-eps; x8=x7; x1=x2=w+arrow_overshoot;
+lft x7=hround u-eps; x8=x7; x1=x2=hround(w+arrow_overshoot);
 y1=y7; y2=y8; y1-y2=spread; .5[y1,y2]=math_axis;
 
-numeric dot_sep; dot_sep:=w/8*arrow_ratio;
 y20=y21=y22=y1;
 y30=y31=y32=y2;
-x20=x30=hround (w-.5dot_sep);
+x20=x30=w-.5dot_sep;
 x20-x21=x21-x22=x30-x31=x31-x32=dot_sep;
 drawdot z20; drawdot z21; drawdot z22;
 drawdot z30; drawdot z31; drawdot z32;
 
-pickup crisp.nib; lft x0=hround u-eps; y0=good.y math_axis;
+pickup crisp.nib;
+lft x0=hround u-eps; y0=good.y math_axis;
 pos3(rule_thickness,0); pos4(rule_thickness,0);
 y3-y1=y2-y4=.24asc_height+eps; x3=x4=x0+6u+eps;
 pos5(rule_thickness,angle(z4-z0)); z5l=z0;
@@ -558,18 +569,19 @@
 t=xpart(p intersectiontimes((0,y0)--(w,y0)));
 filldraw z0..{z4-z9}z4l--subpath (0,t) of\\(z4r{z9-z4}..z6r)
  --subpath (t,0) of\\(z3r{z9-z3}..z5r)--z3l{z9-z3}..z0 & cycle;  % arrowhead
-penlabels(0,1,2,3,4,5,6,7,8,9); endchar;
+penlabels(0,1,2,3,4,5,6,7,8,9,20,21,22,30,31,32); endchar;
 
 cmchar "Triple left dashed arrow head"; 
 compute_spread(.45x_height#,.55x_height#); 
 beginchar(slot_DASHhead,arrow_head_width#,triple_height); 
-numeric dot_sep; dot_sep:=w/8*arrow_ratio;
-adjust_fit(0,0); pickup rule.nib; penpos1(rule_thickness,90); 
-penpos2(rule_thickness,90); penpos3(1.5bar,0); penpos4(1.5bar,0); 
-y0=y1=y2=math_axis;
-lft x0=hround u; x0'=x0''=x0; 
-y1'=y1+spread;y1''=y1-spread; y0'=y1'; y0''=y1''; 
-x53=x53'=x53''=hround (w-.5dot_sep);
+adjust_fit(0,0); pickup rule.nib;
+pos1(rule_thickness,90); pos2(rule_thickness,90);
+pos3(rule_thickness,0); pos4(rule_thickness,0); 
+y0=y1=y2=math_axis; x1=x2+eps;
+lft x0=hround u-eps; x0'=x0''=x0; x1'=x1''=x1;
+y1'=y1+spread; y1''=y1-spread; y0'=y1'; y0''=y1'';
+
+x53=x53'=x53''=w-.5dot_sep;
 x51-x50=x52-x51=x53-x52=dot_sep;
 x50=x50'=x50''; x51=x51'=x51''; x52=x52'=x52''; 
 y50=y51=y52=y53=math_axis;
@@ -578,15 +590,16 @@
 drawdot z50; drawdot z51; drawdot z52; drawdot z53;
 drawdot z50'; drawdot z51'; drawdot z52'; drawdot z53';
 drawdot z50''; drawdot z51''; drawdot z52''; drawdot z53'';
-x1l:=x1r:=x1:=x2+eps;
+
 pickup crisp.nib;  
 y3-y0'=y0''-y4=.24asc_height+eps; x3=x4=x0+6u+eps; 
-pos5(bar,angle(z4-z0)); z5l=z0; pos6(bar,angle(z3-z0)); 
-z6l=z0; z9=.381966[.5[z3,z4],z0]; erase filldraw 
-z0..{z3-z9}z3--(0,y3) 
- --(0,y4)--z4{z9-z4}..z0& cycle; numeric t; path p; 
-p=z4r{z9-z4}..z6r; t=xpart(p 
-intersectiontimes((0,y2l)--(w,y2l))); x2=xpart point t of p; 
+pos5(rule_thickness,angle(z4-z0)); z5l=z0;
+pos6(rule_thickness,angle(z3-z0)); z6l=z0;
+z9=.381966[.5[z3,z4],z0];
+erase filldraw z0..{z3-z9}z3--(0,y3) 
+ --(0,y4)--z4{z9-z4}..z0& cycle;
+numeric t; path p; p=z4r{z9-z4}..z6r;
+t=xpart(p intersectiontimes((0,y2l)--(w,y2l))); x2=xpart point t of p; 
 filldraw z0..{z4-z9}z4l--subpath (0,t) of\\(z4r{z9-z4}..z6r) 
  --z2l---z1l..z1r---z2r--subpath (t,0) of\\(z3r{z9-z3}..z5r) 
  --z3l{z9-z3}..z0 & cycle;  % arrowhead and stem 
@@ -611,12 +624,11 @@
 filldraw z0..{z4-z9}z4r--subpath (0,t) of\\(z4l{z9-z4}..z6r)
  --z2l---z1l..z1r---z2r--subpath (t,0) of\\(z3l{z9-z3}..z5r)
  --z3r{z9-z3}..z0 & cycle;  % arrowhead and stem
-
 x10=0; y10=math_axis+.12asc_height+eps;
-pickup pencircle scaled rule_thickness; 
-draw z10{right}..z1{right}; 
-
-penlabels(0,1,2,3,4,5,6,9); endchar;
+x11=-o; y11=y10;
+pickup rule.nib;
+draw z11..z10{right}..z1{right}; 
+penlabels(0,1,2,3,4,5,6,9,10); endchar;
 
 cmchar "Single right dashed arrow head";
 compute_spread(.45x_height#,.55x_height#);
@@ -636,28 +648,27 @@
  --z2l---z1l..z1r---z2r--subpath (t,0) of\\(z3l{z9-z3}..z5r)
  --z3r{z9-z3}..z0 & cycle;  % arrowhead and stem
 pickup rule.nib;
-numeric dot_sep; dot_sep:=w/8*arrow_ratio;
-y13=y12=y11=y10=y9; x10=hround(.5dot_sep);
-x12-x11=x13-x12=x11-x10=dot_sep;
+y13=y12=y11=y10=y0; x10=.5dot_sep;
+x13-x12=x12-x11=x11-x10=dot_sep;
 drawdot z10; drawdot z11; drawdot z12; drawdot z13;
-penlabels(0,1,2,3,4,5,6,9,10,11,12); endchar;
+penlabels(0,1,2,3,4,5,6,9,10,11,12,13); endchar;
 
 cmchar "Double right dashed arrow head";
 compute_spread(.45x_height#,.55x_height#);
 beginchar(slot_Dashright,arrow_head_width#,double_height);
 adjust_fit(0,0); pickup rule.nib;
-lft x1=hround 0 - arrow_overshoot; x2=x1; x7=x8=w-hround u-eps;
+x1=x2=hround(0-arrow_overshoot); rt x7=w-hround u-eps; x8=x7;
 y1=y7; y2=y8; y1-y2=spread; .5[y1,y2]=math_axis;
 
-numeric dot_sep; dot_sep:=w/8*arrow_ratio;
 y20=y21=y22=y1;
 y30=y31=y32=y2;
-x20=x30=hround .5dot_sep;
+x20=x30=.5dot_sep;
 x21-x20=x22-x21=x31-x30=x32-x31=dot_sep;
 drawdot z20; drawdot z21; drawdot z22;
 drawdot z30; drawdot z31; drawdot z32;
 
-pickup crisp.nib; rt x0=hround(w-u)+eps; y0=good.y math_axis;
+pickup crisp.nib;
+rt x0=hround(w-u)+eps; y0=good.y math_axis;
 pos3(rule_thickness,0); pos4(rule_thickness,0);
 y3-y1=y2-y4=.24asc_height+eps; x3=x4=x0-6u-eps;
 pos5(rule_thickness,angle(z4-z0)); z5l=z0;
@@ -669,18 +680,19 @@
 t=xpart(p intersectiontimes((0,y0)--(w,y0)));
 filldraw z0..{z4-z9}z4r--subpath (0,t) of\\(z4l{z9-z4}..z6r)
  --subpath (t,0) of\\(z3l{z9-z3}..z5r)--z3r{z9-z3}..z0 & cycle;  % arrowhead
-penlabels(0,1,2,3,4,5,6,7,8,9); endchar;
+penlabels(0,1,2,3,4,5,6,7,8,9,20,21,22,30,31,32); endchar;
 
 cmchar "Triple right dashed arrow head"; 
 compute_spread(.45x_height#,.55x_height#); 
 beginchar(slot_DASHright,arrow_head_width#,triple_height); 
-numeric dot_sep; dot_sep:=w/8*arrow_ratio;
-adjust_fit(0,0); pickup rule.nib; penpos1(rule_thickness,90); 
-penpos2(rule_thickness,90); penpos3(1.5bar,0); penpos4(1.5bar,0); 
-y0=y1=y2=math_axis; x1=hround(0-arrow_overshoot);  
-rt x0=hround (w-u); x0'=x0''=x0; x1'=x1''=x1; 
-y1'=y1+spread;y1''=y1-spread; y0'=y1'; y0''=y1''; 
-x50=x50'=x50''=hround .5dot_sep;
+adjust_fit(0,0); pickup rule.nib;
+pos1(rule_thickness,90); pos2(rule_thickness,90);
+pos3(rule_thickness,0); pos4(rule_thickness,0); 
+y0=y1=y2=math_axis; x1=x2-eps;
+rt x0=hround(w-u)+eps; x0'=x0''=x0; x1'=x1''=x1;
+y1'=y1+spread; y1''=y1-spread; y0'=y1'; y0''=y1'';
+
+x50=x50'=x50''=.5dot_sep;
 x51-x50=x52-x51=x53-x52=dot_sep;
 x51=x51'=x51'';x 52=x52'=x52''; x53=x53'=x53'';
 y50=y51=y52=y53=math_axis;
@@ -689,15 +701,16 @@
 drawdot z50; drawdot z51; drawdot z52; drawdot z53;
 drawdot z50'; drawdot z51'; drawdot z52'; drawdot z53';
 drawdot z50''; drawdot z51''; drawdot z52''; drawdot z53'';
-x1l:=x1r:=x2-eps;
+
 pickup crisp.nib;  
 y3-y0'=y0''-y4=.24asc_height+eps; x3=x4=x0-6u-eps; 
-penpos5(bar,angle(z0-z4)); z5r=z0; penpos6(bar,angle(z0-z3)); 
-z6r=z0; z9=.381966[.5[z3,z4],z0]; erase filldraw 
-z0..{z3-z9}z3--(w,y3)--(w,y4)--z4{z9-z4}..z0& cycle; 
-numeric t; path p; 
-p=z4l{z9-z4}..z6l; t=xpart(p intersectiontimes((0,y2l)--(w,y2l))); 
-x2=xpart point t of p; 
+penpos5(bar,angle(z0-z4)); z5r=z0;
+penpos6(bar,angle(z0-z3)); z6r=z0;
+z9=.381966[.5[z3,z4],z0];
+erase filldraw z0..{z3-z9}z3--(w,y3)
+ --(w,y4)--z4{z9-z4}..z0& cycle; 
+numeric t; path p; p=z4l{z9-z4}..z6l;
+t=xpart(p intersectiontimes((0,y2l)--(w,y2l))); x2=xpart point t of p; 
 filldraw z0..{z4-z9}z4r--subpath (0,t) of\\(z4l{z9-z4}..z6l) 
  --z2l---z1l..z1r---z2r--subpath (t,0) of\\(z3l{z9-z3}..z5l) 
  --z3r{z9-z3}..z0 & cycle;  % arrowhead and stem 
@@ -709,11 +722,10 @@
 compute_spread(.45x_height#,.55x_height#); 
 beginchar(slot_Headnone,arrow_head_width#,double_height); 
 adjust_fit(0,0); pickup rule.nib;
+lft x1=hround u; x1=x2; x7=x8=hround(w+arrow_overshoot); 
 y1=y7; y2=y8; y1-y2=spread; .5[y1,y2]=math_axis;
-x7=hround(w+arrow_overshoot); lft x1=hround u;
-x7=x8; x1=x2;	
 draw z1--z7; draw z2--z8;  % bars
-endchar;
+penlabels(1,2,7,8); endchar;
 
 cmchar "Wide double left arrow end"; 
 compute_spread(.45x_height#,.55x_height#); 
@@ -722,9 +734,9 @@
 y1=y2=math_axis+.24asc_height+eps;
 y3=y4=math_axis-.24asc_height-eps;
 x2=hround(w+arrow_overshoot); lft x1=hround u;
-x2=x4; x1=x3;	
+x1=x3; x2=x4;	
 draw z1--z2; draw z3--z4;  % bars
-endchar;
+penlabels(1,2,3,4); endchar;
 
 cmchar "Triple left arrow end"; 
 compute_spread(.45x_height#,.55x_height#); 
@@ -734,16 +746,16 @@
 x7=hround(w+arrow_overshoot); lft x1=hround u;
 x7=x8=x9; x1=x2=x3;	
 draw z1--z7; draw z2--z8; draw z3--z9; % bars
-endchar;
+penlabels(1,2,3,7,8,9); endchar;
 
 cmchar "Left squiggly arrow end";
 compute_spread(.45x_height#,.55x_height#);
 beginchar(slot_squignone,arrow_head_width#,single_height); 
-adjust_fit(0,0); 
-pickup pencircle scaled rule_thickness; 
+adjust_fit(0,0); pickup pencircle scaled rule_thickness; 
 squig_u:=.25arrow_ext_width;
 acc_w:=0;
 x2:=w; y2:=math_axis+.12asc_height+eps;
+x0=x2+o; y0=y2; draw z0..z2;
 forever:
  exitif (acc_w+squig_u > w);
  x1:=x2; y1:=y2;
@@ -751,52 +763,45 @@
  draw z1{left}..{left}z2;
  acc_w:=acc_w+squig_u;
 endfor
-endchar;
+penlabels(1,2,3); endchar;
 
 cmchar "Single left dashed arrow end";
 compute_spread(.45x_height#,.55x_height#);
 beginchar(slot_dashnone,arrow_head_width#,single_height);
 adjust_fit(0,0); pickup rule.nib;
-numeric dot_sep; dot_sep:=w/8*arrow_ratio;
-y15=y14=y13=y12=y11=y10=math_axis; x10=hround(w-.5dot_sep);
-x14-x15=x13-x14=x11-x12=x12-x13=x10-x11=dot_sep;
-drawdot z10; drawdot z11; drawdot z12; drawdot z13; drawdot z14; 
-penlabels(0,1,2,3,4,5,6,9,10,11,12,13,14); endchar;
+2(w-x10)=dot_sep; y10=math_axis; drawdot z10;
+for j=11 thru 14:
+  x[j-1]-x[j]=dot_sep; y[j]=y[j-1]; drawdot z[j];
+endfor
+penlabels(range 10 thru 14); endchar;
 
 cmchar "Double left dashed arrow end";
 compute_spread(.45x_height#,.55x_height#);
 beginchar(slot_Dashnone,arrow_head_width#,double_height);
 adjust_fit(0,0); pickup rule.nib;
-numeric dot_sep; dot_sep:=w/8*arrow_ratio;
-y15=y14=y13=y12=y11=y10; y25=y24=y23=y22=y21=y20; 
-y15-y25=spread; .5[y15,y25]=math_axis;
-x15=x25; x14=x24; x13=x23; x12=x22; x11=x21; x10=x20;
-x10=hround(w-.5dot_sep); x14-x15=x13-x14=x11-x12=x12-x13=x10-x11=dot_sep;
-drawdot z10; drawdot z11; drawdot z12; drawdot z13; drawdot z14; 
-drawdot z20; drawdot z21; drawdot z22; drawdot z23; drawdot z24; 
-penlabels(0,1,2,3,4,5,6,9,10,11,12,13,14,20,21,22,23,24); endchar;
+x10=x20=w-.5dot_sep;
+y10-y20=spread; .5[y10,y20]=math_axis;
+drawdot z10; drawdot z20;
+for j=11 thru 14:
+  x[j-1]-x[j]=dot_sep; y[j]=y[j-1]; drawdot z[j];
+  x[j]=x[j+10]; y[j+10]=y[j+10-1]; drawdot z[j+10];
+endfor
+penlabels(range 10 thru 14,range 20 thru 24); endchar;
 
 cmchar "Triple left dashed arrow end"; 
 compute_spread(.45x_height#,.55x_height#); 
 beginchar(slot_DASHnone,arrow_head_width#,triple_height); 
 adjust_fit(0,0); pickup rule.nib;
-numeric dot_sep; dot_sep:=w/8*arrow_ratio;
-y15=y14=y13=y12=y11=y10; 
-y25=y24=y23=y22=y21=y20; 
-y35=y34=y33=y32=y31=y30; 
-y15-y25=y25-y35=spread; .5[y15,y35]=math_axis;
-x15=x25=x35; 
-x14=x24=x34; 
-x13=x23=x33; 
-x12=x22=x32; 
-x11=x21=x31; 
-x10=x20=x30;
-x10=hround(w-.5dot_sep); 
-x14-x15=x13-x14=x11-x12=x12-x13=x10-x11=dot_sep;
-drawdot z10; drawdot z11; drawdot z12; drawdot z13; drawdot z14; 
-drawdot z20; drawdot z21; drawdot z22; drawdot z23; drawdot z24; 
-drawdot z30; drawdot z31; drawdot z32; drawdot z33; drawdot z34; 
-endchar;
+x10=x20=x30=w-.5dot_sep;
+y10-y20=y20-y30=spread; .5[y10,y30]=math_axis;
+drawdot z10; drawdot z20; drawdot z30;
+for j=11 thru 14:
+  x[j-1]-x[j]=dot_sep; y[j]=y[j-1]; drawdot z[j];
+  x[j]=x[j+10]=x[j+20];
+  y[j+10]=y[j+10-1]; drawdot z[j+10];
+  y[j+20]=y[j+20-1]; drawdot z[j+20];
+endfor
+penlabels(range 10 thru 14,range 20 thru 24,range 30 thru 34); endchar;
 
 % 8 simple right arrow ends
 
@@ -804,18 +809,19 @@
 compute_spread(.45x_height#,.55x_height#);
 beginchar(slot_headrightnone,arrow_head_width#,single_height);
 adjust_fit(0,0); pickup rule.nib;
-y0=y1=math_axis; x1=hround (0-arrow_overshoot); rt x0=hround(w-u);
-draw z0--z1; endchar;
+rt x1=hround(w-u); x2=hround(0-arrow_overshoot);
+y1=y2=math_axis;
+draw z1--z2;
+penlabels(1,2); endchar;
 
 cmchar "Double right arrow end";
 compute_spread(.45x_height#,.55x_height#);
 beginchar(slot_Headrightnone,arrow_head_width#,double_height);
 adjust_fit(0,0); pickup rule.nib;
+rt x7=hround(w-u); x7=x8; x1=x2=hround(0-arrow_overshoot); 
 y1=y7; y2=y8; y1-y2=spread; .5[y1,y2]=math_axis;
-lft x1=hround(0-arrow_overshoot); rt x7=hround(w-u); 
-x7=x8; x1=x2;	
 draw z1--z7; draw z2--z8;  % bars
-endchar;
+penlabels(1,2,7,8); endchar;
 
 cmchar "Wide double right arrow end";
 compute_spread(.45x_height#,.55x_height#);
@@ -823,29 +829,29 @@
 adjust_fit(0,0); pickup rule.nib;
 y1=y2=math_axis+.24asc_height+eps;
 y3=y4=math_axis-.24asc_height-eps;
-lft x1=hround(0-arrow_overshoot); rt x2=hround(w-u); 
-x3=x1; x4=x2;	
+x1=hround(0-arrow_overshoot); rt x2=hround(w-u); 
+x1=x3; x2=x4; 
 draw z1--z2; draw z3--z4;  % bars
-endchar;
+penlabels(1,2,3,4); endchar;
 
 cmchar "Triple right arrow end";
 compute_spread(.45x_height#,.55x_height#);
 beginchar(slot_HEADrightnone,arrow_head_width#,triple_height);
 adjust_fit(0,0); pickup rule.nib;
 y1=y7; y2=y8; y3=y9; y1-y2=y2-y3=spread; y2=math_axis;
-lft x1=hround(0-arrow_overshoot); rt x7=hround(w-u); 
+x1=hround(0-arrow_overshoot); rt x7=hround(w-u); 
 x7=x8=x9; x1=x2=x3;	
 draw z1--z7; draw z2--z8; draw z3--z9; % bars
-endchar;
+penlabels(1,2,3,7,8,9); endchar;
 
 cmchar "Right squiggly arrow end";
 compute_spread(.45x_height#,.55x_height#);
 beginchar(slot_squigrightnone,arrow_head_width#,single_height); 
-adjust_fit(0,0); 
-pickup pencircle scaled rule_thickness; 
+adjust_fit(0,0); pickup pencircle scaled rule_thickness; 
 squig_u:=.25arrow_ext_width;
 acc_w:=0;
 x2:=0; y2:=math_axis+.12asc_height+eps;
+x0=x2-o; y0=y2; draw z0..z2;
 forever:
  exitif (acc_w+squig_u > w);
  x1:=x2; y1:=y2; 
@@ -853,60 +859,51 @@
  draw z1{right}..{right}z2;
  acc_w:=acc_w+squig_u;
 endfor
-endchar;
+penlabels(1,2,3); endchar;
 
 cmchar "Single right dashed arrow end";
 compute_spread(.45x_height#,.55x_height#);
 beginchar(slot_dashrightnone,arrow_head_width#,single_height);
 adjust_fit(0,0); pickup rule.nib;
-numeric dot_sep; dot_sep:=w/8*arrow_ratio;
-y15=y14=y13=y12=y11=y10=math_axis; x10=hround(.5dot_sep);
-x15-x14=x14-x13=x12-x11=x13-x12=x11-x10=dot_sep;
-drawdot z10; drawdot z11; drawdot z12; drawdot z13; drawdot z14; 
-penlabels(0,1,2,3,4,5,6,9,10,11,12,13,14); endchar;
+x10=.5dot_sep; y10=math_axis; drawdot z10;
+for j=11 thru 14:
+  x[j]-x[j-1]=dot_sep; y[j]=y[j-1]; drawdot z[j];
+endfor
+penlabels(range 10 thru 14); endchar;
 
 cmchar "Double right dashed arrow end";
 compute_spread(.45x_height#,.55x_height#);
 beginchar(slot_Dashrightnone,arrow_head_width#,double_height);
 adjust_fit(0,0); pickup rule.nib;
-numeric dot_sep; dot_sep:=w/8*arrow_ratio;
-y15=y14=y13=y12=y11=y10;
-y25=y24=y23=y22=y21=y20;
-y15-y25=spread; .5[y15,y25]=math_axis; 
-x15=x25; x14=x24; x13=x23; x12=x22; x11=x21; x10=x20;
-x10=hround(.5dot_sep); x15-x14=x14-x13=x12-x11=x13-x12=x11-x10=dot_sep;
-drawdot z10; drawdot z11; drawdot z12; drawdot z13; drawdot z14; 
-drawdot z20; drawdot z21; drawdot z22; drawdot z23; drawdot z24; 
-penlabels(0,1,2,3,4,5,6,9,10,11,12,13,14,20,21,22,23,24); endchar;
+x10=x20=.5dot_sep;
+y10-y20=spread; .5[y10,y20]=math_axis;
+drawdot z10; drawdot z20;
+for j=11 thru 14:
+  x[j]-x[j-1]=dot_sep; y[j]=y[j-1]; drawdot z[j];
+  x[j]=x[j+10]; y[j+10]=y[j+10-1]; drawdot z[j+10];
+endfor
+penlabels(range 10 thru 14,range 20 thru 24); endchar;
 
 cmchar "Triple right dashed arrow end"; 
 compute_spread(.45x_height#,.55x_height#); 
 beginchar(slot_DASHrightnone,arrow_head_width#,triple_height); 
 adjust_fit(0,0); pickup rule.nib;
-numeric dot_sep; dot_sep:=w/8*arrow_ratio;
-y15=y14=y13=y12=y11=y10; 
-y25=y24=y23=y22=y21=y20; 
-y35=y34=y33=y32=y31=y30; 
-y15-y25=y25-y35=spread; .5[y15,y35]=math_axis;
-x15=x25=x35; 
-x14=x24=x34; 
-x13=x23=x33; 
-x12=x22=x32; 
-x11=x21=x31; 
-x10=x20=x30;
-x10=hround .5dot_sep; 
-x14-x15=x13-x14=x11-x12=x12-x13=x10-x11=-dot_sep;
-drawdot z10; drawdot z11; drawdot z12; drawdot z13; drawdot z14; 
-drawdot z20; drawdot z21; drawdot z22; drawdot z23; drawdot z24; 
-drawdot z30; drawdot z31; drawdot z32; drawdot z33; drawdot z34; 
-endchar;
+x10=x20=x30=.5dot_sep;
+y10-y20=y20-y30=spread; .5[y10,y30]=math_axis;
+drawdot z10; drawdot z20; drawdot z30;
+for j=11 thru 14:
+  x[j]-x[j-1]=dot_sep; y[j]=y[j-1]; drawdot z[j];
+  x[j]=x[j+10]=x[j+20];
+  y[j+10]=y[j+10-1]; drawdot z[j+10];
+  y[j+20]=y[j+20-1]; drawdot z[j+20];
+endfor
+penlabels(range 10 thru 14,range  20 thru 24,range  30 thru 34); endchar;
 
 % 5 arrow extension pieces
 
 cmchar "Double arrow extension";
 compute_spread(.45x_height#,.55x_height#);
 beginchar(slot_doubleext,arrow_ext_width#,double_height);
-italcorr h#*slant-.5u#;
 adjust_fit(0,0); pickup rule.nib;
 lft x1=hround(0-arrow_overshoot);   % hround u-eps; 
 x3=x1; 
@@ -914,12 +911,11 @@
 y1=y2; y3=y4; y1-y3=spread; .5[y1,y3]=math_axis;
 draw z1--z2;  % upper bar
 draw z3--z4;  % lower bar
-labels(1,2,3,4); endchar;
+penlabels(1,2,3,4); endchar;
 
 cmchar "Wide double arrow extension";
 compute_spread(.45x_height#,.55x_height#);
 beginchar(slot_widedoubleext,arrow_ext_width#,wide_double_height);
-italcorr h#*slant-.5u#;
 adjust_fit(0,0); pickup rule.nib;
 lft x1=hround 0 - arrow_overshoot;
 x3=x1; 
@@ -928,91 +924,83 @@
 y3=y4=math_axis-.24asc_height-eps;
 draw z1--z2;  % upper bar
 draw z3--z4;  % lower bar
-labels(1,2,3,4); endchar;
+penlabels(1,2,3,4); endchar;
 
 cmchar "Triple arrow extension";
 compute_spread(.45x_height#,.55x_height#);
 beginchar(slot_tripleext,arrow_ext_width#,triple_height);
-italcorr h#*slant-.5u#;
 adjust_fit(0,0); pickup rule.nib;
 lft x1=hround 0 - arrow_overshoot; x5=x3=x1; x6=x2=x4=w-x1; 
 y1=y2; y3=y4; y1-y3=2spread; y5=y6=.5[y1,y3]=math_axis;
 draw z1--z2;  % upper bar
 draw z3--z4;  % lower bar
 draw z5--z6;  % middle bar
-labels(1,2,3,4,5,6); endchar;
+penlabels(1,2,3,4,5,6); endchar;
 
 cmchar "Squiggly left gaped arrow extension";
 compute_spread(.45x_height#,.55x_height#);
 beginchar(slot_squiggapleft,arrow_ext_width#,single_height); 
-adjust_fit(0,0); 
+adjust_fit(0,0); pickup pencircle scaled rule_thickness; 
 y2=y4; y1=y3=y5; y3-y4=.24asc_height+eps;
 .5[y3,y4]=math_axis;
 x2-x1=x3-x2=x4-x3=x5-x4;
 x1=0; x5=w;
-pickup pencircle scaled rule_thickness; 
-draw z1{right}..z2{right}..z3{right}..z4{right}..{right}z5; 
-unfill (5/6w,-d)--(7/6w,-d)--(7/6w,h)--(5/6w,h)--cycle;
-endchar;
+x0=x1-o; y0=y1;
+path p; p:=z1{right}..z2{right}..z3{right}..z4{right}..{right}z5; 
+numeric t; t=xpart(p intersectiontimes((5/6w,-d)--(5/6w,h)));
+draw z0..z1{right}..z2{right}..z3{right}..
+        z4{right}..{direction t of p}(point t of p); 
+penlabels(1,2,3,4,5); endchar;
 
 cmchar "Squiggly right gaped arrow extension";
 compute_spread(.45x_height#,.55x_height#);
 beginchar(slot_squiggapright,arrow_ext_width#,single_height); 
-adjust_fit(0,0); 
+adjust_fit(0,0); pickup pencircle scaled rule_thickness; 
 y2=y4; y1=y3=y5; y3-y4=.24asc_height+eps;
 .5[y3,y4]=math_axis;
 x2-x1=x3-x2=x4-x3=x5-x4;
-x1=0; x5=w;
-pickup pencircle scaled rule_thickness; 
-draw z1{right}..z2{right}..z3{right}..z4{right}..{right}z5; 
-unfill (1/6w,-d)--(-1/6w,-d)--(-1/6w,h)--(1/6w,h)--cycle;
-endchar;
+x1=0; x5=w; 
+x6=x5+o; y5=y6;
+path p; p:=z1{right}..z2{right}..z3{right}..z4{right}..{right}z5; 
+numeric t; t=xpart(p intersectiontimes((1/6w,-d)--(1/6w,h)));
+draw (point t of p){direction t of p}..z2{right}..z3{right}..
+    z4{right}..{right}z5..z6; 
+penlabels(1,2,3,4,5); endchar;
 
 cmchar "Double dashed arrow extension";
 compute_spread(.45x_height#,.55x_height#);
 beginchar(slot_Dashext,arrow_ext_width#,double_height);
-italcorr h#*slant-.5u#;
 adjust_fit(0,0); pickup rule.nib;
-numeric dot_sep; dot_sep:=w/8;
-y0=y1=y2=y3=y4=y5=y6=y7=y8; 
-y10=y11=y12=y13=y14=y15=y16=y17=y18;
-y0-y10=spread; .5[y0,y10]=math_axis;
-x0=0; x10=x0; x11=x1; x12=x2; x13=x3; x14=x4; x15=x5; x16=x6;
-x17=x7; x18=x8;
-2(x1-x0)=x2-x1=x3-x2=x4-x3=x5-x4=x6-x5=x7-x6=x8-x7=dot_sep;
-drawdot z1; drawdot z2; drawdot z3; drawdot z4;
-drawdot z5; drawdot z6; drawdot z7; drawdot z8;
-drawdot z11; drawdot z12; drawdot z13; drawdot z14;
-drawdot z15; drawdot z16; drawdot z17; drawdot z18;
-labels(1,2,3,4,5,6,7,8,10,11,12,13,14,15,16,17,18); endchar;
+x0=x10=0; y0-y10=spread; .5[y0,y10]=math_axis;
+2(x1-x0)=dot_sep; x1=x11; y1=y0; y11=y10;
+drawdot z1; drawdot z11;
+for j=2 thru 8:
+  x[j]-x[j-1]=dot_sep; y[j]=y[j-1]; drawdot z[j];
+  x[j]=x[j+10]; y[j+10]=y[j+10-1]; drawdot z[j+10];
+endfor
+penlabels(range 1 thru 8,range 11 thru 18); endchar;
 
-cmchar "Triple dash arrow extension";
+cmchar "Triple dashed arrow extension";
 compute_spread(.45x_height#,.55x_height#);
 beginchar(slot_DASHext,arrow_ext_width#,triple_height);
-italcorr h#*slant-.5u#;
 adjust_fit(0,0); pickup rule.nib;
-numeric dot_sep; dot_sep:=w/8;
-y0=y1=y2=y3=y4=y5=y6=y7=y8; 
-y10=y11=y12=y13=y14=y15=y16=y17=y18;
-y20=y21=y22=y23=y24=y25=y26=y27=y28;
-y10-y20=y0-y10=spread; .5[y0,y20]=math_axis;
-x0=0; x10=x0; x21=x11=x1; x22=x12=x2; x23=x13=x3; 
-x24=x14=x4; x25=x15=x5; x26=x16=x6; x27=x17=x7; x28=x18=x8;
-2(x1-x0)=x2-x1=x3-x2=x4-x3=x5-x4=x6-x5=x7-x6=x8-x7=dot_sep;
-drawdot z1; drawdot z2; drawdot z3; drawdot z4;
-drawdot z5; drawdot z6; drawdot z7; drawdot z8;
-drawdot z11; drawdot z12; drawdot z13; drawdot z14;
-drawdot z15; drawdot z16; drawdot z17; drawdot z18;
-drawdot z21; drawdot z22; drawdot z23; drawdot z24;
-drawdot z25; drawdot z26; drawdot z27; drawdot z28;
-labels(1,2,3,4,5,6); endchar;
+x0=x10=x20=0; y0-y10=y10-y20=spread; .5[y0,y20]=math_axis;
+2(x1-x0)=dot_sep; x1=x11=x21; y1=y0; y11=y10; y21=y20;
+drawdot z1; drawdot z11; drawdot z21;
+for j=2 thru 8:
+  x[j]-x[j-1]=dot_sep; y[j]=y[j-1]; drawdot z[j];
+  x[j]=x[j+10]=x[j+20];
+  y[j+10]=y[j+10-1]; drawdot z[j+10];
+  y[j+20]=y[j+20-1]; drawdot z[j+20];
+endfor
+penlabels(range 1 thru 8,range 11 thru 18,range 21 thru 28); endchar;
 
 % 7 arrow negation pieces
 
 cmchar "Double arrow negation";
 compute_spread(.45x_height#,.55x_height#);
-beginchar(slot_doubleneg,0pt#,double_height); 
-pickup rule.nib;
+beginchar(slot_doubleneg,4u#,double_height); 
+adjust_fit(-(2u#+letter_fit#),-(2u#+letter_fit#)); pickup rule.nib;
 y1-y3=spread; .5[y1,y3]=math_axis;
 y5-y1=.24asc_height+eps;
 char_center(100); top y101=top y5; x101=x100+2u;
@@ -1021,8 +1009,8 @@
 
 cmchar "Wider double arrow negation";
 compute_spread(.45x_height#,.55x_height#);
-beginchar(slot_widedoubleneg,0pt#,wide_double_height); 
-pickup rule.nib;
+beginchar(slot_widedoubleneg,4u#,wide_double_height); 
+adjust_fit(-(2u#+letter_fit#),-(2u#+letter_fit#)); pickup rule.nib;
 y1=math_axis+.24asc_height+eps;
 y5-y1=.24asc_height+eps;
 char_center(100); top y101=top y5; x101=x100+2u;
@@ -1031,8 +1019,8 @@
 
 cmchar "Triple arrow negation";
 compute_spread(.45x_height#,.55x_height#);
-beginchar(slot_tripleneg,0pt#,triple_height); 
-pickup rule.nib;
+beginchar(slot_tripleneg,4u#,triple_height); 
+adjust_fit(-(2u#+letter_fit#),-(2u#+letter_fit#)); pickup rule.nib;
 y1-y3=2spread; .5[y1,y3]=math_axis;
 y5-y1=.24asc_height+eps;
 char_center(100); top y101=top y5; x101=x100+2u;
@@ -1041,18 +1029,18 @@
 
 cmchar "Squiggly arrow negation";
 compute_spread(.45x_height#,.55x_height#);
-beginchar(slot_squigneg,0pt#,single_height); 
-pickup rule.nib;
+beginchar(slot_squigneg,3u#,single_height); 
+adjust_fit(-(1.5u#+letter_fit#),-(1.5u#+letter_fit#)); pickup rule.nib;
 y1=math_axis;
 y3-y1=.24asc_height+eps;
-char_center(100); top y101=top y3; x101=x100+2u;
+char_center(100); top y101=top y3; x101=x100+1.5u;
 char_negate(100,101,102);
 endchar;
 
 cmchar "Single dashed arrow negation";
 compute_spread(.45x_height#,.55x_height#);
-beginchar(slot_dashneg,0pt#,single_height); 
-pickup rule.nib;
+beginchar(slot_dashneg,4u#,single_height); 
+adjust_fit(-(2u#+letter_fit#),-(2u#+letter_fit#));  pickup rule.nib;
 y1=math_axis;
 y3-y1=.24asc_height+eps;
 char_center(100); top y101=top y3; x101=x100+2u;
@@ -1061,8 +1049,8 @@
 
 cmchar "Double dashed arrow negation";
 compute_spread(.45x_height#,.55x_height#);
-beginchar(slot_Dashneg,0pt#,double_height); 
-pickup rule.nib;
+beginchar(slot_Dashneg,4u#,double_height); 
+adjust_fit(-(2u#+letter_fit#),-(2u#+letter_fit#));  pickup rule.nib;
 y1-y3=spread; .5[y1,y3]=math_axis;
 y5-y1=.24asc_height+eps;
 char_center(100); top y101=top y5; x101=x100+2u;
@@ -1071,8 +1059,8 @@
 
 cmchar "Triple dashed arrow negation";
 compute_spread(.45x_height#,.55x_height#);
-beginchar(slot_DASHneg,0pt#,triple_height); 
-pickup rule.nib;
+beginchar(slot_DASHneg,4u#,triple_height); 
+adjust_fit(-(2u#+letter_fit#),-(2u#+letter_fit#));  pickup rule.nib;
 y1-y3=2spread; .5[y1,y3]=math_axis;
 y5-y1=.24asc_height+eps;
 char_center(100); top y101=top y5; x101=x100+2u;
@@ -1091,7 +1079,7 @@
 y5-y1=.24asc_height+eps;
 char_center(100); top y101=top y5; x101=x100+2u;
 char_negate(100,101,102);
-labels(1,2,3,4); endchar;
+penlabels(1,2,3,4); endchar;
 
 cmchar "Wider double negated arrow extension";
 compute_spread(.45x_height#,.55x_height#);
@@ -1105,7 +1093,7 @@
 y5-y1=.24asc_height+eps;
 char_center(100); top y101=top y5; x101=x100+2u;
 char_negate(100,101,102);
-labels(1,2,3,4); endchar;
+penlabels(1,2,3,4); endchar;
 
 cmchar "Triple negated arrow extension";
 compute_spread(.45x_height#,.55x_height#);
@@ -1119,28 +1107,28 @@
 y7-y1=.24asc_height+eps;
 char_center(100); top y101=top y7; x101=x100+2u;
 char_negate(100,101,102);
-labels(1,2,3,4,5,6); endchar;
+penlabels(1,2,3,4,5,6); endchar;
 
 cmchar "Squiggly negated arrow extension";
 compute_spread(.45x_height#,.55x_height#);
 beginchar(slot_squignegext,arrow_ext_width#,single_height); 
-adjust_fit(0,0); 
+adjust_fit(0,0); pickup pencircle scaled rule_thickness; 
 y2=y4; y1=y3=y5; y3-y4=.24asc_height+eps;
 .5[y3,y4]=math_axis;
 x2-x1=x3-x2=x4-x3=x5-x4;
 x1=0; x5=w;
-pickup pencircle scaled rule_thickness; 
-draw z1{right}..{right}z2..{right}z3..{right}z4..{right}z5; 
-y3:=math_axis+.24asc_height+eps;
-char_center(100); top y101=top y3; x101=x100+2u;
+x0=x1-o; x6=x5+o;
+y0=y1; y6=y5;
+draw z0..z1{right}..{right}z2..{right}z3..{right}z4..{right}z5..z6; 
+y6:=math_axis+.24asc_height+eps;
+char_center(100); top y101=top y6; x101=x100+1.5u;
 char_negate(100,101,102);
-endchar;
+penlabels(1,2,3,4,5); endchar;
 
 cmchar "Single dashed negated arrow extension";
 compute_spread(.45x_height#,.55x_height#);
 beginchar(slot_dashnegext,arrow_ext_width#,single_height); 
-pickup rule.nib;
-numeric dot_sep; dot_sep:=w/8;
+adjust_fit(0,0); pickup rule.nib;
 x0=0; 
 y0=y1=y2=y3=y4=y5=y6=y7=y8=math_axis;
 2(x1-x0)=x2-x1=x3-x2=x4-x3=x5-x4=x6-x5=x7-x6=x8-x7=dot_sep;
@@ -1149,14 +1137,12 @@
 y10-y1=.24asc_height+eps;
 char_center(100); top y101=top y10; x101=x100+2u;
 char_negate(100,101,102);
-labels(0,1,2,3,4,5,6,7,8,100); endchar;
+penlabels(range 1 thru 8); endchar;
 
 cmchar "Double dashed negated arrow extension";
 compute_spread(.45x_height#,.55x_height#);
 beginchar(slot_Dashnegext,arrow_ext_width#,double_height);
-italcorr h#*slant-.5u#;
 adjust_fit(0,0); pickup rule.nib;
-numeric dot_sep; dot_sep:=w/8;
 y0=y1=y2=y3=y4=y5=y6=y7=y8; 
 y10=y11=y12=y13=y14=y15=y16=y17=y18;
 y0-y10=spread; .5[y0,y10]=math_axis;
@@ -1170,14 +1156,12 @@
 y9-y1=.24asc_height+eps;
 char_center(100); top y101=top y9; x101=x100+2u;
 char_negate(100,101,102);
-labels(1,2,3,4,5,6,7,8,10,11,12,13,14,15,16,17,18); endchar;
+penlabels(range 1 thru 8,range 11 thru 18); endchar;
 
 cmchar "Triple dashed negated arrow extension";
 compute_spread(.45x_height#,.55x_height#);
 beginchar(slot_DASHnegext,arrow_ext_width#,triple_height);
-italcorr h#*slant-.5u#;
 adjust_fit(0,0); pickup rule.nib;
-numeric dot_sep; dot_sep:=w/8;
 y0=y1=y2=y3=y4=y5=y6=y7=y8; 
 y10=y11=y12=y13=y14=y15=y16=y17=y18;
 y20=y21=y22=y23=y24=y25=y26=y27=y28;
@@ -1194,51 +1178,63 @@
 y77-y1=.24asc_height+eps;
 char_center(100); top y101=top y77; x101=x100+2u;
 char_negate(100,101,102);
-labels(1,2,3,4,5,6); endchar;
+penlabels(range 1 thru 8,range 11 thru 18,range 21 thru 28); endchar;
 
-% 7 arrow gaps
+% 8 arrow gaps
+
+cmchar "Single gap";
+compute_spread(.45x_height#,.55x_height#);
+beginchar(slot_GAP,arrow_ext_width#/3,single_height);
+adjust_fit(0,0);
+endchar;
 
 cmchar "Double gap";
 compute_spread(.45x_height#,.55x_height#);
 beginchar(slot_doublegap,arrow_ext_width#/3,double_height); 
+adjust_fit(0,0);
 endchar;
 
 cmchar "Wide double gap";
 compute_spread(.45x_height#,.55x_height#);
 beginchar(slot_widedoublegap,arrow_ext_width#/3,wide_double_height); 
+adjust_fit(0,0);
 endchar;
 
 cmchar "Triple gap";
 compute_spread(.45x_height#,.55x_height#);
 beginchar(slot_triplegap,arrow_ext_width#/3,triple_height); 
+adjust_fit(0,0);
 endchar;
 
 cmchar "Squiggly gap";
 compute_spread(.45x_height#,.55x_height#);
 beginchar(slot_squiggap,arrow_ext_width#/3,single_height); 
+adjust_fit(0,0);
 endchar;
 
 cmchar "Single dashed gap";
 compute_spread(.45x_height#,.55x_height#);
 beginchar(slot_dashgap,arrow_ext_width#/3,single_height); 
+adjust_fit(0,0);
 endchar;
 
 cmchar "Double dashed gap";
 compute_spread(.45x_height#,.55x_height#);
 beginchar(slot_Dashgap,arrow_ext_width#/3,double_height); 
+adjust_fit(0,0);
 endchar;
 
 cmchar "Triple dashed gap";
 compute_spread(.45x_height#,.55x_height#);
 beginchar(slot_DASHgap,arrow_ext_width#/3,triple_height); 
+adjust_fit(0,0);
 endchar;
 
 % 7 gap extensions
 
 cmchar "Double gap extension";
 compute_spread(.45x_height#,.55x_height#);
-beginchar(slot_doublegapext,4/3arrow_ext_width#,double_height); 
-italcorr h#*slant-.5u#;
+beginchar(slot_doublegapext,3/2arrow_ext_width#,double_height); 
 adjust_fit(0,0); pickup rule.nib;
 lft x1=hround(0-arrow_overshoot);   % hround u-eps; 
 x3=x1; 
@@ -1248,12 +1244,11 @@
 y1=y2=y5=y7; y3=y4=y6=y8; y1-y3=spread; .5[y1,y3]=math_axis;
 draw z1--z5; draw z7--z2;  % upper bar
 draw z3--z6; draw z8--z4;  % lower bar
-labels(1,2,3,4); endchar;
+penlabels(1,2,3,4,5,6,7,8); endchar;
 
 cmchar "Wide double gap extension";
 compute_spread(.45x_height#,.55x_height#);
-beginchar(slot_widedoublegapext,4/3arrow_ext_width#,wide_double_height); 
-italcorr h#*slant-.5u#;
+beginchar(slot_widedoublegapext,3/2arrow_ext_width#,wide_double_height); 
 adjust_fit(0,0); pickup rule.nib;
 lft x1=hround (0 - arrow_overshoot);
 x3=x1; 
@@ -1264,12 +1259,11 @@
 y6=y8=y3=y4=math_axis-.24asc_height-eps;
 draw z1--z5; draw z7--z2;  % upper bar
 draw z3--z6; draw z8--z4;  % lower bar
-labels(1,2,3,4); endchar;
+penlabels(1,2,3,4,5,6,7,8); endchar;
 
 cmchar "Triple gap extension";
 compute_spread(.45x_height#,.55x_height#);
-beginchar(slot_triplegapext,4/3arrow_ext_width#,triple_height); 
-italcorr h#*slant-.5u#;
+beginchar(slot_triplegapext,3/2arrow_ext_width#,triple_height); 
 adjust_fit(0,0); pickup rule.nib;
 lft x1=hround 0 - arrow_overshoot; x5=x3=x1; x6=x2=x4=w-x1; 
 x7=x8=x9=3/8w; x10=x11=x12=5/8w;
@@ -1278,7 +1272,7 @@
 draw z1--z7; draw z10--z2;  % upper bar
 draw z3--z8; draw z11--z4;  % lower bar
 draw z5--z9; draw z12--z6;  % middle bar
-labels(1,2,3,4,5,6); endchar;
+penlabels(1,2,3,4,5,6,7,8,9,10,11,12); endchar;
 
 cmchar "Squiggly gap extension";
 compute_spread(.45x_height#,.55x_height#);
@@ -1286,71 +1280,76 @@
 adjust_fit(0,0); 
 y2=y4; y1=y3=y5; y3-y4=.24asc_height+eps;
 .5[y3,y4]=math_axis;
-x5=w; x1=0; x5-x4=x4-x3=x3-x2=x2-x1;
+x1=0; x5=w; x5-x4=x4-x3=x3-x2=x2-x1;
+x0=x1-o; x6=x5+o;
+y0=y1; y6=y5;
 pickup pencircle scaled rule_thickness; 
-draw z1{right}..z2{right}..z3{right}..z4{right}..z5{right}; 
-unfill (1/3w,-d)--(2/3w,-d)--(2/3w,h)--(1/3w,h)--cycle;
-endchar;
+path p; p:=z1{right}..z2{right}..z3{right}..z4{right}..z5{right}; 
+numeric t[];
+t1=xpart(p intersectiontimes((1/3w,-d)--(1/3w,h)));
+t2=xpart(p intersectiontimes((2/3w,-d)--(2/3w,h)));
+draw z0..z1{right}..z2{right}..{direction t1 of p}(point t1 of p);
+draw (point t2 of p){direction t2 of p}..z4{right}..z5{right}..z6; 
+penlabels(1,2,3,4,5); endchar;
 
 cmchar "Single dash gap extension";
 compute_spread(.45x_height#,.55x_height#);
-beginchar(slot_dashgapext,4/3arrow_ext_width#,single_height); 
-pickup rule.nib;
-numeric dot_sep; dot_sep:=3/32w;
-y0=y1=y2=y3=y4=y5=y6=y7=y8=math_axis;
-x0=0;
-2(x1-x0)=x2-x1=x3-x2=dot_sep;
-w-x6=x1; w-x7=x2; w-x8=x3;
-drawdot z1; drawdot z2; drawdot z3;
-drawdot z6; drawdot z7; drawdot z8;
-labels(0,1,2,3,4,5,6,7,8); endchar;
+beginchar(slot_dashgapext,3/2arrow_ext_width#,single_height); 
+adjust_fit(0,0); pickup rule.nib;
+x0=0; y0=math_axis;
+2(x1-x0)=dot_sep; x1'=w-x1; y1'=y1=y0;
+drawdot z1; drawdot z1';
+for j=2 thru 4:
+  w-x[j]'=x[j]=x[j-1]+dot_sep; y[j]'=y[j]=y0;
+  drawdot z[j]; drawdot z[j]';
+endfor
+penlabels(1,2,3,4,1',2',3',4'); endchar;
 
 cmchar "Double dash gap extension";
 compute_spread(.45x_height#,.55x_height#);
-beginchar(slot_Dashgapext,4/3arrow_ext_width#,double_height); 
-italcorr h#*slant-.5u#;
+beginchar(slot_Dashgapext,3/2arrow_ext_width#,double_height); 
 adjust_fit(0,0); pickup rule.nib;
-numeric dot_sep; dot_sep:=w/8;
-y0=y1=y2=y3=y4=y5=y6=y7=y8; 
-y10=y11=y12=y13=y14=y15=y16=y17=y18;
-y0-y10=spread; .5[y0,y10]=math_axis;
-x11=x1; x12=x2; x13=x3; x16=x6; x17=x7; x18=x8;
-x0=0; 2(x1-x0)=x2-x1=x3-x2=dot_sep;
-w-x6=x1; w-x7=x2; w-x8=x3;
-drawdot z1; drawdot z2; drawdot z3; 
-drawdot z6; drawdot z7; drawdot z8;
-drawdot z11; drawdot z12; drawdot z13; 
-drawdot z16; drawdot z17; drawdot z18;
-labels(1,2,3,4,5,6,7,8,10,11,12,13,14,15,16,17,18); endchar;
+x0=0; y0-y10=spread; .5[y0,y10]=math_axis;
+2(x1-x0)=dot_sep; x1=x11; x1'=x11'=w-x1;
+y1'=y1=y0; y11'=y11=y10;
+drawdot z1; drawdot z1';
+drawdot z11; drawdot z11';
+for j=2 thru 4:
+  w-x[j]'=x[j]=x[j-1]+dot_sep; y[j]'=y[j]=y0;
+  x[j]=x[j+10]; x[j]'=x[j+10]';
+  y[j+10]'=y[j+10]=y[j+10-1];
+  drawdot z[j]; drawdot z[j]';
+  drawdot z[j+10]; drawdot z[j+10]';
+endfor
+penlabels(1,2,3,4,11,12,13,14,1',2',3',4',11',12',13',14'); endchar;
 
 cmchar "Triple dash gap extension";
 compute_spread(.45x_height#,.55x_height#);
-beginchar(slot_DASHgapext,4/3arrow_ext_width#,triple_height); 
-italcorr h#*slant-.5u#;
+beginchar(slot_DASHgapext,3/2arrow_ext_width#,triple_height); 
 adjust_fit(0,0); pickup rule.nib;
-numeric dot_sep; dot_sep:=w/8;
-y0=y1=y2=y3=y4=y5=y6=y7=y8; 
-y10=y11=y12=y13=y14=y15=y16=y17=y18;
-y20=y21=y22=y23=y24=y25=y26=y27=y28;
-y10-y20=y0-y10=spread; .5[y0,y20]=math_axis;
-x21=x11=x1; x22=x12=x2; x23=x13=x3; 
-x26=x16=x6; x27=x17=x7; x28=x18=x8;
-x0=0; 2(x1-x0)=x2-x1=x3-x2=dot_sep;
-w-x6=x1; w-x7=x2; w-x8=x3;
-drawdot z1; drawdot z2; drawdot z3; 
-drawdot z6; drawdot z7; drawdot z8;
-drawdot z11; drawdot z12; drawdot z13; 
-drawdot z16; drawdot z17; drawdot z18;
-drawdot z21; drawdot z22; drawdot z23; 
-drawdot z26; drawdot z27; drawdot z28;
-labels(1,2,3,4,5,6); endchar;
+x0=0; y0-y10=y10-y20=spread; .5[y0,y20]=math_axis;
+2(x1-x0)=dot_sep; x1=x11=x21; x1'=x11'=x21'=w-x1;
+y1'=y1=y0; y11'=y11=y10; y21'=y21=y20;
+drawdot z1; drawdot z1';
+drawdot z11; drawdot z11';
+drawdot z21; drawdot z21';
+for j=2 thru 4:
+  w-x[j]'=x[j]=x[j-1]+dot_sep; y[j]'=y[j]=y0;
+  x[j]=x[j+10]=x[j+20]; x[j]'=x[j+10]'=x[j+20]';
+  y[j+10]'=y[j+10]=y[j+10-1];
+  y[j+20]'=y[j+20]=y[j+20-1];
+  drawdot z[j]; drawdot z[j]';
+  drawdot z[j+10]; drawdot z[j+10]';
+  drawdot z[j+20]; drawdot z[j+20]';
+endfor
+penlabels(1,2,3,4,11,12,13,14,21,22,23,24,
+  1',2',3',4',11',12',13',14',21',22',23',24'); endchar;
 
 cmchar "Left harpoon up"; 
 compute_spread(.45x_height#,.55x_height#); 
 beginchar(slot_harpoonup,arrow_head_width#,single_height);  
-adjust_fit(0,0);  
+adjust_fit(0,0); pickup crisp.nib;  
 path topleft;
-pickup crisp.nib;  
 pos1(rule_thickness,90); pos2(rule_thickness,90); 
 pos3(bar,0); pos4(bar,0); y0=y1=y2=math_axis; 
 x1=hround(w+arrow_overshoot); % x1+.5rule_thickness=hround(w-u); 
@@ -1368,8 +1367,7 @@
 cmchar "Right harpoon up"; 
 compute_spread(.45x_height#,.55x_height#); 
 beginchar(slot_harpoonupright,arrow_head_width#,single_height);  
-adjust_fit(0,0);  
-pickup crisp.nib;  
+adjust_fit(0,0); pickup crisp.nib;  
 path topright; % for bottom right half arrow   
 topright:=topleft reflectedabout ((w/2,0),(w/2,h)); 
 filldraw topright; endchar;
@@ -1377,8 +1375,7 @@
 cmchar "Left harpoon down"; 
 compute_spread(.45x_height#,.55x_height#); 
 beginchar(slot_harpoondown,arrow_head_width#,single_height);  
-adjust_fit(0,0);  
-pickup crisp.nib;  
+adjust_fit(0,0); pickup crisp.nib;  
 path botleft;
 botleft:=topleft reflectedabout ((0,math_axis),(w,math_axis));
 filldraw botleft; endchar;
@@ -1386,8 +1383,7 @@
 cmchar "Right harpoon down"; 
 compute_spread(.45x_height#,.55x_height#); 
 beginchar(slot_harpoondownright,arrow_head_width#,single_height);  
-adjust_fit(0,0);  
-pickup crisp.nib;  
+adjust_fit(0,0); pickup crisp.nib;  
 path botright; 
 botright:=topright reflectedabout ((0,math_axis),(w,math_axis));
 filldraw botright; endchar;
@@ -1395,8 +1391,7 @@
 cmchar "Left harpoons up";
 compute_spread(.45x_height#,.55x_height#); 
 beginchar(slot_harpoonsup,arrow_head_width#,double_height);  
-adjust_fit(0,0);  
-pickup crisp.nib;  
+adjust_fit(0,0); pickup crisp.nib;  
 path tmp;
 tmp:=topleft shifted (0,.5spread); % shift above math_axis 
 filldraw tmp; 
@@ -1409,8 +1404,7 @@
 cmchar "Left harpoons down";
 compute_spread(.45x_height#,.55x_height#); 
 beginchar(slot_harpoonsdown,arrow_head_width#,double_height);  
-adjust_fit(0,0);  
-pickup crisp.nib;  
+adjust_fit(0,0); pickup crisp.nib;  
 path tmp;
 tmp:=botleft shifted (0,-.5spread);
 filldraw tmp; 
@@ -1423,8 +1417,7 @@
 cmchar "Right harpoons up";
 compute_spread(.45x_height#,.55x_height#); 
 beginchar(slot_harpoonsupright,arrow_head_width#,double_height);  
-adjust_fit(0,0);  
-pickup crisp.nib;  
+adjust_fit(0,0); pickup crisp.nib;  
 path tmp;
 tmp:=topright shifted (0,.5spread); 
 filldraw tmp;
@@ -1437,8 +1430,7 @@
 cmchar "Right harpoons down";
 compute_spread(.45x_height#,.55x_height#); 
 beginchar(slot_harpoonsdownright,arrow_head_width#,double_height);  
-adjust_fit(0,0);  
-pickup crisp.nib;  
+adjust_fit(0,0); pickup crisp.nib;  
 path tmp;
 tmp:=botright shifted (0,-.5spread); 
 filldraw tmp;
@@ -1451,8 +1443,7 @@
 cmchar "Left harpoons"; 
 compute_spread(.45x_height#,.55x_height#); 
 beginchar(slot_harpoons,arrow_head_width#,double_height);  
-adjust_fit(0,0);  
-pickup crisp.nib;  
+adjust_fit(0,0); pickup crisp.nib;  
 path tmp;
 tmp:=topleft shifted (0,.5spread); filldraw tmp;
 tmp:=botleft shifted (0,-.5spread); filldraw tmp;
@@ -1461,8 +1452,7 @@
 cmchar "Right harpoons"; 
 compute_spread(.45x_height#,.55x_height#); 
 beginchar(slot_harpoonsright,arrow_head_width#,double_height);  
-adjust_fit(0,0);  
-pickup crisp.nib;  
+adjust_fit(0,0); pickup crisp.nib;  
 path tmp;
 tmp:=topright shifted (0,.5spread); filldraw tmp;
 tmp:=botright shifted (0,-.5spread); filldraw tmp;
@@ -1471,8 +1461,7 @@
 cmchar "Left arrows"; 
 compute_spread(.45x_height#,.55x_height#); 
 beginchar(slot_arrows,arrow_head_width#,wide_double_height); 
-adjust_fit(0,0); 
-pickup crisp.nib; 
+adjust_fit(0,0); pickup crisp.nib; 
 pos1(rule_thickness,90); 
 pos2(rule_thickness,90); pos3(bar,0); pos4(bar,0); 
 y0=y1=y2=math_axis; 
@@ -1489,40 +1478,37 @@
  --z3l{z9-z3}..z0 & cycle;  % arrowhead and stem 
 path p;
 p:=ldarr shifted (0,y2-y4+eps); filldraw p; % top arrow 
-p:= ldarr shifted (0,y2-y3-eps); filldraw p; % bottom arrow 
+p:=ldarr shifted (0,y2-y3-eps); filldraw p; % bottom arrow 
 endchar; 
 
 cmchar "Left arrows up"; 
 compute_spread(.45x_height#,.55x_height#); 
 beginchar(slot_arrowsup,arrow_head_width#,wide_double_height); 
-adjust_fit(0,0); 
-pickup crisp.nib; 
+adjust_fit(0,0); pickup crisp.nib; 
 path p;
 p:=ldarr shifted (0,.24asc_height+eps); filldraw p;
 pickup rule.nib; 
 y5:=y6:=math_axis-.24asc_height-eps;
 x5=hround(w+arrow_overshoot); lft x6=hround u; 
 draw z5---z6;
-endchar;
+endchar; 
 
 cmchar "Left arrows down"; 
 compute_spread(.45x_height#,.55x_height#); 
 beginchar(slot_arrowsdown,arrow_head_width#,wide_double_height); 
-adjust_fit(0,0); 
-pickup crisp.nib; 
+adjust_fit(0,0); pickup crisp.nib; 
 path p;
 p:=ldarr shifted (0,-.24asc_height-eps); filldraw p;
 pickup rule.nib; 
 y5:=y6:=math_axis+.24asc_height+eps;
 x5=hround(w+arrow_overshoot); lft x6=hround u; 
 draw z5---z6;
-endchar;
+endchar; 
 
 cmchar "Right arrows"; 
 compute_spread(.45x_height#,.55x_height#); 
 beginchar(slot_arrowsright,arrow_head_width#,wide_double_height); 
-adjust_fit(0,0); 
-pickup crisp.nib; 
+adjust_fit(0,0); pickup crisp.nib; 
 path rdarr;
 rdarr:=ldarr reflectedabout ((w/2,0),(w/2,h));
 path p;
@@ -1533,8 +1519,7 @@
 cmchar "Right arrows up"; 
 compute_spread(.45x_height#,.55x_height#); 
 beginchar(slot_arrowsupright,arrow_head_width#,wide_double_height); 
-adjust_fit(0,0); 
-pickup crisp.nib; 
+adjust_fit(0,0); pickup crisp.nib; 
 path p;
 p:=rdarr shifted (0,.24asc_height+eps); filldraw p; % top arrow 
 y5:=y6:=math_axis-.24asc_height-eps;
@@ -1546,8 +1531,7 @@
 cmchar "Right arrows down"; 
 compute_spread(.45x_height#,.55x_height#); 
 beginchar(slot_arrowsdownright,arrow_head_width#,wide_double_height); 
-adjust_fit(0,0); 
-pickup crisp.nib; 
+adjust_fit(0,0); pickup crisp.nib; 
 path p;
 p:=rdarr shifted (0,-.24asc_height-eps); filldraw p;
 y5:=y6:=math_axis+.24asc_height+eps;
@@ -1581,7 +1565,7 @@
 y11=y12=math_axis;
 pickup rule.nib;
 draw z11---z12;
-penlabels(0,1,2,3,4,5,6,9); endchar; 
+endchar; 
  
 cmchar "Left feathers";
 beginchar(slot_feathers,arrow_head_width#,wide_double_height); 
@@ -1592,7 +1576,7 @@
 y11=y12=math_axis;
 pickup rule.nib;
 draw z11---z12;
-endchar;
+endchar; 
 
 cmchar "Right feather"; 
 beginchar(slot_featherright,arrow_head_width#,wide_double_height); 
@@ -1603,7 +1587,7 @@
 y11=y12=math_axis;
 pickup rule.nib;
 draw z11---z12;
-penlabels(0,1,2,3,4,5,6,9); endchar; 
+endchar; 
 
 cmchar "Right feathers"; 
 beginchar(slot_feathersright,arrow_head_width#,single_height); 
@@ -1614,7 +1598,7 @@
 y11=y12=math_axis;
 pickup rule.nib;
 draw z11---z12;
-penlabels(0,1,2,3,4,5,6,9); endchar; 
+endchar; 
  
 cmchar "Right hook up";
 compute_spread(.45x_height#,.55x_height#);
@@ -1624,7 +1608,7 @@
 y1-y3=spread; y2=.5[y1,y3]; y3=math_axis=y4;
 x4=hround(-arrow_overshoot);
 draw z1{right}...z2{down}...z3{left}---z4;  % hook
-labels(1,2,3); endchar;
+penlabels(1,2,3,4); endchar;
 
 cmchar "Right hook down";
 compute_spread(.45x_height#,.55x_height#);
@@ -1634,7 +1618,7 @@
 y3-y1=spread; y2=.5[y1,y3]; y3=math_axis=y4;
 x4=hround(-arrow_overshoot);
 draw z1{right}...z2{up}...z3{left}---z4;  % hook
-labels(1,2,3); endchar;
+penlabels(1,2,3,4); endchar;
 
 cmchar "Right curly up";  
 beginchar(slot_curlyupright,arrow_head_width#,.8asc_height#,0#); 
@@ -1658,30 +1642,30 @@
 q=z15--z10{right}..tension0.8..{up}z11..tension0.8..{left}z12 
 ..tension0.8..{down}z13--z14; 
 draw q; 
-penlabels(0,1,2,3,4,5,6,9,10,11,12,13,14); endchar; 
+penlabels(0,1,2,3,4,5,6,9,10,11,12,13,14,15); endchar; 
  
 cmchar "Right curly down";  
 beginchar(slot_curlydownright,arrow_head_width#,.8asc_height#,0#); 
-adjust_fit(0,0); 
-pickup pencircle scaled rule_thickness; 
+adjust_fit(0,0); pickup pencircle scaled rule_thickness; 
 q:=q reflectedabout ((0,math_axis),(w,math_axis)); 
-draw q; endchar; 
+draw q;
+penlabels(0,1,2,3,4,5,6,9,10,11,12,13,14,15); endchar; 
  
 cmchar "Left curly down";  
 beginchar(slot_curlydown,arrow_head_width#,.8asc_height#,0#); 
-adjust_fit(0,0); 
-pickup pencircle scaled rule_thickness; 
+adjust_fit(0,0); pickup pencircle scaled rule_thickness; 
 q:=q reflectedabout ((w/2+eps,-d),(w/2+eps,h)); 
-draw q; endchar; 
+draw q;
+penlabels(0,1,2,3,4,5,6,9,10,11,12,13,14,15); endchar; 
  
 cmchar "Left curly up";  
 beginchar(slot_curlyup,arrow_head_width#,.8asc_height#,0#); 
-adjust_fit(0,0); 
-pickup pencircle scaled rule_thickness; 
+adjust_fit(0,0); pickup pencircle scaled rule_thickness; 
 q:=q reflectedabout ((0,math_axis),(w,math_axis)); 
-draw q; endchar; 
+draw q; 
+penlabels(0,1,2,3,4,5,6,9,10,11,12,13,14,15); endchar; 
 
-bye.
+endinput