home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / unixtex-6.1b-bin3.lha / lib / texmf / fonts / ams / euler / src / eubase.mf < prev    next >
Text File  |  1996-10-12  |  14KB  |  412 lines

  1. %% @metafontfile{
  2. %%     filename="eubase.mf",
  3. %%     version="2.1",
  4. %%     date="30-MAY-1991",
  5. %%     filetype="Metafont: base",
  6. %%     copyright="Copyright (C) American Mathematical Society,
  7. %%            all rights reserved.  Copying of this file is
  8. %%            authorized only if either:
  9. %%            (1) you make absolutely no changes to your copy
  10. %%                including name; OR
  11. %%            (2) if you do make changes, you first rename it to some
  12. %%                other name.",
  13. %%     author="American Mathematical Society",
  14. %%     address="American Mathematical Society,
  15. %%            Technical Support Department,
  16. %%            P. O. Box 6248,
  17. %%            Providence, RI 02940,
  18. %%            USA",
  19. %%     telephone="401-455-4080 or (in the USA) 800-321-4AMS",
  20. %%     email="Internet: Tech-Support@Math.AMS.org",
  21. %%     codetable="ISO/ASCII",
  22. %%     checksumtype="line count",
  23. %%     checksum="412",
  24. %%     keywords="amsfonts, tex, metafont , euler ",
  25. %%     abstract="This is the base file for use with 
  26. %%            the euler fonts in AMSFonts 2.1."
  27. %%     }
  28. %
  29. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  30. % base file for Euler Fonts, by David Siegel and John Hobby
  31.  
  32.  %def define_euler_pixels(text t) =
  33.  %forsuffixes $=t: $=$.#*hppp; endfor enddef;
  34.  
  35.  
  36.  
  37.      pixperem = ptsize*pt;
  38.  
  39. %  Beginning of change for version 2.1
  40. %  replaced the next four lines:
  41. %h#=ptsize/programem;
  42. %v#=h#*aspect_ratio;
  43. % define_euler_pixels(h,v);
  44. %v#:=h#; % DEK (I doubt if aspect_ratio<>1 will work, but this does help)
  45.  
  46. %    with the following five lines:
  47. if unknown xscale_factor: xscale_factor := 1; fi
  48. h# = ptsize * xscale_factor / programem;
  49. v# = ptsize / programem;
  50. h = h#*hppp;
  51. v = v#*vppp;
  52.  
  53. %    end of change for version 2.1                     4/4/91 NGB
  54.  
  55.      define_pixels(leftside, rightside);
  56. %     h = pixperem/programem;
  57. %     v = pixperem/programem*aspect_ratio;
  58.  
  59.       dandch = 3.94h;          %     dandch = (pixperem/935);
  60.       dandcv = 3.94v;         %     dandcv = (pixperem/935);
  61.  
  62.         nwdh#  = h#*programem/925;     % h*3.784
  63.         nwdv#  = v#*programem/925;     % v*3.784
  64.         nwdh   = h*programem/925;
  65.         nwdv   = v*programem/925;
  66. % dandc == dan mills and carol twombly; nwd == dave siegel -- DEK
  67.      adjustx:=  3.92;
  68.      adjusty:=  3.92;
  69.  
  70. save_leftside#:=leftside#; save_rightside#:=rightside#; % DEK
  71. def more_side(expr s_sharp) =
  72.  leftside#:=save_leftside#+s_sharp; rightside#:=save_rightside#+s_sharp;
  73.  define_pixels(leftside,rightside);
  74. enddef;
  75.  
  76. % ----- Fontbegin, Charbegin -----------------------------------
  77. % --------------------------------------------------------------
  78.  
  79. transform rot;
  80.  
  81. def charbegin(expr c,w_sharp,h_sharp,d_sharp) =
  82.  begingroup
  83.   charcode:=if known c: byte c else: 0 fi;
  84.   W := w_sharp*pt;
  85.   chardx:=round(W+leftside+rightside);     % desired width of character in pixels
  86.   charwd:=w_sharp+leftside#+rightside#;    charht:=h_sharp;  chardp:=d_sharp;
  87. % charic:=0; clearxy; clearit; clearpen; scantokens extra_beginchar;
  88. % rot := identity;
  89.   charic:=0; clearxy; clearit; clearpen; % DEK
  90.   rot := identity; scantokens extra_beginchar;
  91.   pair tiept[];
  92.  enddef;
  93.  
  94. def endchar(expr addwidth_sharp) =
  95.  scantokens extra_endchar;
  96. %if proofing>0: makebox(proofrule); fi
  97.  addwidth:=addwidth_sharp*pt;
  98. %currentpicture := currentpicture shifted (leftside+addwidth,0);
  99. xoffset:=leftside+addwidth;
  100. H:=charht*pt; D:=chardp*pt;
  101. if known nohashmarks:;
  102. else:
  103.  if proofing>0:
  104.   for y=0,H,-D*pt:
  105.     proofrule((-xoffset,y),(10-xoffset,y));
  106.     proofrule((chardx-10-xoffset,y),(chardx-xoffset,y)); endfor % horizontals
  107.   for x=-xoffset,chardx-xoffset:
  108.     proofrule((x,10-D),(x,-D)); proofrule((x,H-10),(x,H)); endfor % verticals fi
  109.  fi
  110. fi
  111. shipit;
  112. %if displaying>0: makebox(screenrule); showit; fi
  113. endgroup enddef;
  114.  
  115. def mathcorr(expr subwidth_sharp) = % DEK
  116.  charic:=subwidth_sharp; charwd:=charwd-charic;
  117. enddef;
  118.  
  119. % -----     TeX Information: ----------------------------------------
  120.  
  121.      fontdimen 1:
  122.  
  123.      0,               % italic correction     degrees
  124.      ptsize/3,          % default spacing (3em)     points
  125.      0,               % stretch          "
  126.      0,               % shrink          "
  127.      (lcbody*v#),           % xheight          "
  128.      ptsize,               % quad               "
  129.      0,               % math space          
  130.      (1400*v#),   % num1 baseline raise, for numerators, display style
  131.      (1000*v#),   % num2 baseline raise, for numerators, non-atop
  132.      (1100*v#),   % num3 baseline raise, for numerators, atop styles
  133.      (1400*v#),     % denom1 amount to lower baselines in display style
  134.      (600*v#),     % denom1 amount to lower baselines in non-display 
  135.      (1500*v#),     % sup1
  136.      (1400*v#),     % sup2 guess at superscript raising again
  137.      (1200*v#),     % sup3
  138.      (depthy*v#),     % sub1 subscripts with no super
  139.      (900*v#),     % sub2 maybe this is off by a little.
  140.      (1500*v#),     % supdrop how much to drop below a large box
  141.      (100*v#),     % supdrop how much to raise above a large box
  142.      2.2(programem*v#),     % size of \comb delimiters for display 
  143.      (programem*v#),     % size of \comb delimiters for non-display 
  144.      (950*v#);     % axisheight center for fraction line
  145.  
  146. font_size     ptsize;
  147.  
  148.  
  149. % Adjusting stems
  150. % revised by DEK to allow highres adjustments, 11 Aug 87
  151.  
  152. vardef set_stem_round(expr slo,s,shi,clo,c,chi) =
  153.  stem_lo:=slo*h; stem_hi:=shi*h; stem_norm:=s*h;
  154.  curve_lo:=clo*h; curve_hi:=chi*h; curve_norm:=c*h;
  155.   save a,b;
  156.   a-b = round (stem_norm - curve_norm);
  157.   a = round(.5(stem_norm + curve_norm + a - b));
  158.   stem_norm_corr := a-stem_norm; % a is normal stem width in pixels
  159.   curve_norm_corr := b-curve_norm; % b is normal curve width in pixels
  160. enddef;
  161.  
  162. def no_stem_round = set_stem_round(-1,-1,-1,-1,-1,-1) enddef;
  163. no_stem_round; % default is to do ordinary rounding
  164.  
  165. % The |stem_round| macro rounds its argument, forcing numbers that look like
  166. % stem widths to round near to |stem_norm|, and similarly forcing vertical curve
  167. % weights to round near to |curve_norm|.
  168.  
  169. def stem_round primary w = if w<0: -stem_rnd(-w) else: stem_rnd(w) fi enddef;
  170.  
  171. def stem_rnd(expr w) =
  172.     round(w
  173.     if (stem_lo<=w) and (w<=stem_hi): +stem_norm_corr
  174.     elseif (curve_lo<=w) and (w<=curve_hi): +curve_norm_corr
  175.     fi)
  176. enddef;
  177.  
  178. % Filling cyclic paths with step width adjustment and rounding
  179.  
  180. % Before calling the |adj_fill| macro, the user should set up an
  181. % array |t[]| and a nonnegative integer |n| so that |t[1]| through |t[n]|
  182. % are time values on some cyclic path |p|.  It should be true that |t[i]<t[j]|
  183. % whenever |i<j|.  Also |t[n]-t[1]| should be less than the length of |p|.
  184. % The |adj_fill| macro takes four lists of time values given as indices into
  185. % the |t| array.  The avoids the necessity of writing \MF\ macros to sort
  186. % the time values.
  187. % Groups of paths are allowed to have points ``tied together.''  This is
  188. % implemented by saving coordinates in a special array of type |pair|
  189. % called |tiept|.  If a path contains a point that is tied to a point in
  190. % an already computed path, then the adjusted coordinates of that point will
  191. % be saved in the |tiept| array.  This array should be made unknown before
  192. % starting a new group of paths; e.g., in |beginchar|.
  193.  
  194.  
  195. % Make |y'a| and |y'b| rounded versions of |y.a| and |y.b|, so that
  196. % |y'a-y'b| is as close as possible to |y.a-y.b|.
  197. % If a time value is given as both fixed and vertical or horizontal then
  198. % |y'a| or |y'b| or both may already be known.  Then we just round what
  199. % we can.
  200.  
  201. vardef rnd_pr_y(suffix a, b) =
  202.   if known y'a: if unknown y'b: y'b-y'a=round(y.b-y.a); fi
  203.   elseif known y'b: y'b-y'a=round(y.b-y.a);
  204.   else:
  205.     y'a-y'b = round(y.a-y.b);
  206.     y'a = round(.5(y.a + y.b + y'a - y'b));
  207.   fi
  208. enddef;
  209.  
  210. % Rounding |x| coordinates is similar except we use the special |stem_round|
  211. % routine.
  212.  
  213. vardef rnd_pr_x(suffix a, b) =
  214. % use the next line if you want to see what channel settings are reasonable
  215. % (also set tracingtitles:=1 in such a case)
  216. % message decimal t.a&","&decimal t.b&":"&decimal((x.b-x.a)/h);
  217.   if known x'a: if unknown x'b: x'b-x'a=stem_round(x.b-x.a); fi
  218.   elseif known x'b: x'b-x'a=stem_round(x.b-x.a);
  219.   else:
  220.     x'a-x'b = stem_round(x.a-x.b);
  221.     x'a = round(.5(x.a + x.b + x'a - x'b));
  222.   fi
  223. enddef;
  224.  
  225.  
  226.  
  227. % Set up a transform |curtx=tx.a| that takes |x.a| into |x'a| and |x.b|
  228. % into |x'b| without slanting or changing $y$-components.
  229.  
  230. vardef set_tx(suffix a,b) =
  231.   save u,v;
  232.   xypart tx.a = yxpart tx.a = 0;
  233.   (x.a,0) transformed tx.a = (x'a,0);
  234.   (u,v) = (x.b,1) transformed tx.a - (x'b,1);
  235.   if known u: xxpart tx.a = yypart tx.a = 1;
  236.         else: (u,v)=origin;
  237.   fi
  238.   curtx := tx.a
  239. enddef;
  240.  
  241.  
  242. % Set up a transform |curty=ty.a| that takes |y.a| into |y'a| and |y.b|
  243. % into |y'b| without slanting or changing $x$-components.
  244.  
  245. vardef set_ty(suffix a,b) =
  246.   save u,v;
  247.   xypart ty.a = yxpart ty.a = 0;
  248.   (0,y.a) transformed ty.a = (0,y'a);
  249.   (u,v) = (1,y.b) transformed ty.a - (1,y'b);
  250.   if known v: xxpart ty.a = yypart ty.a = 1;
  251.         else: (u,v)=origin;
  252.   fi
  253.   curty := ty.a
  254. enddef;
  255.  
  256.  
  257. % The following macros ensure that |x'i| or |y'i| agree with the current
  258. % transform.  It is important that this be done for all relevant |i| each
  259. % time |set_tx| or |set_ty| is called.  Since some points may be tied to
  260. % others, this can affect which |x'j| and |y'j| are known.  Future calls to
  261. % |set_tx| and |set_ty| should be based on the most up to date possible
  262. % information.
  263.  
  264. vardef yset@# = (0,y'@#) = (0,y@#) transformed curty; enddef;
  265. vardef xset@# = (x'@#,0) = (x@#,0) transformed curtx; enddef;
  266.  
  267.  
  268. % Apply |set_txy| to each pair indices |a,b| such that |xy'[a]| and |xy'[b]|
  269. % are known, but |xy'[c] is unknown for all |c| between |a| and |b|.
  270. % This leaves the appropriate initial transformation in |curtx| or |curty|.
  271. % The |xyset| parameter is either |xset| or |yset| as explained above.
  272.  
  273. vardef set_trans(suffix xy, set_txy, xyset) =
  274.   save previ, firsti;
  275.   for i=1 upto n: if known xy'[i]:
  276.       if known firsti:
  277.      set_txy([previ], [i]);
  278.      for j=previ+1 upto i-1: xyset[j]; endfor
  279.       else: firsti = i;
  280.       fi
  281.       previ := i;
  282.   fi endfor     
  283.   if known firsti:
  284.     for i=1 upto firsti: if known xy'[i]:
  285.       set_txy([previ], [i]);
  286.       if previ>=firsti:
  287.      for j=previ+1 upto n: xyset[j]; endfor
  288.      for j=1 upto i-1: xyset[j]; endfor
  289.       else:
  290.      for j=previ+1 upto i-1: xyset[j]; endfor
  291.       fi
  292.       previ:=i;
  293.     fi endfor
  294.   else:
  295.     for i=1 upto n: xyset[i]; endfor
  296.   fi
  297. enddef;
  298.  
  299.  
  300.  
  301. % Return the transformed $i$th segement of |p_path| as defined by the time
  302. % values in |t[]|, updating |curtx| and |curty| if appropriate.
  303.  
  304. vardef new_seg(expr i) =
  305.   save p; path p;
  306.   if known tx[i]: curtx:=tx[i]; fi
  307.   if known ty[i]: curty:=ty[i]; fi
  308.   p = subpath (t[i],t[i+1]) of p_path transformed (curtx transformed curty);
  309.   p
  310. enddef;
  311.  
  312.  
  313.  
  314. % The following macros are used only when |t| entries are readjusted:
  315.  
  316.  
  317. % Find the first time on the path |p| where the direction is |dir| or |-dir|.
  318.  
  319. def extremetime expr dir of p =
  320.   begingroup save a,b;
  321.   a = directiontime dir of p; if a<0: a:=infinity; fi
  322.   b = directiontime -dir of p; if b<0: b:=infinity; fi
  323.   if a<b: a else: b fi
  324.   endgroup
  325. enddef;
  326.  
  327.  
  328. % Adjust the time value |tt| to the nearest time when the direction of |p_path|
  329. % is |dir| or |-dir|.
  330.  
  331. vardef adj_t(suffix tt)(expr dir) =
  332.   save p, a, b; path p;
  333.   p = subpath (tt,tt+nn) of p_path & cycle;
  334.   a = extremetime dir of p;
  335.   a := if a<1: a[tt,floor tt+1] else: a+floor tt fi;
  336.   b = extremetime dir of reverse p;
  337.   b := if b<1: b[tt,ceiling tt-1] else: ceiling tt - b fi;
  338.   tt := if b+a>2tt: b else: a fi;
  339. enddef;
  340.  
  341.  
  342. % Issue an error message when |t[i]>t[i+1]| after the above adjustment process.
  343.  
  344. vardef bad_order(expr i) =
  345.   initerim showstopping:=0;
  346.   show t[i], t[i+1];
  347.   errmessage "Adjusted t entries "&decimal i&" and "&decimal(i+1)
  348.           &" are out of order. (See above)";
  349. enddef;
  350.  
  351.  
  352. % The |adj_fill| macro performs the entire adjustment and filling based on
  353. % the following parameters: a list |tfx| of |t| indices for points whose
  354. % $x$-coordinates should not be moved during the adjustment process, a similar
  355. % list |tfy| for $y$-coordinates, a list of pairs $(i,j)$ where $i$ is a |t|
  356. % index and |tiept[j]| is the corresponding tie point, lists |tv| and |th| of
  357. % pairs of |t| indices that correspond to opposite sides of vertical and
  358. % horizontal strokes, and finally a cyclic path |p|.  (Note the scaling by |h|
  359. % and |v|.)
  360.  
  361. vardef adj_fill@#(text tfx, tfy, tie, tv, th)(expr p) =
  362. % message str@#; % that's for use with the stem-round message above
  363.   save p_path, nn, x, y, tx, ty, curtx, curty;
  364.   path p_path, p_path';
  365.   transform tx[], ty[], curtx, curty;
  366.   p_path = p transformed (identity xscaled h yscaled v transformed rot);
  367.   nn = length p_path;
  368.   if proofing>1:
  369.     makelabel(str @#, point 0 of p_path);
  370.     for i=1 upto nn-1: makelabel(decimal i, point i of p_path); endfor
  371.   fi
  372.     forsuffixes i=tfx: x.fix.i=1; endfor          % Prepare for |adj_t| calls.
  373.     forsuffixes i=tfy: y.fix.i=1; endfor
  374.     for w=1 tv: if pair w: (x.fix[xpart w],x.fix[ypart w]) = (1,1); fi endfor
  375.     for w=1 th: if pair w: (y.fix[xpart w],y.fix[ypart w]) = (1,1); fi endfor
  376.     for i=1 upto n:
  377.       if t[i]>floor t[i]:
  378.      if unknown x.fix[i]: adj_t(t[i],right); fi
  379.      if unknown y.fix[i]: adj_t(t[i],up); fi
  380.       fi
  381.     endfor
  382.     t[n+1] := t1+nn;
  383.     for i=1 upto n: if t[i]>t[i+1]: bad_order(i); fi endfor
  384.   for i=1 upto n: z[i] = point t[i] of p_path; endfor
  385.   forsuffixes i=tfx: x'i =x.i; endfor
  386.   forsuffixes i=tfy: y'i =y.i; endfor
  387.   for w=1 tie: if pair w: z'[xpart w] = tiept[ypart w]; fi endfor
  388.   for w=1 tv: if pair w: rnd_pr_x([xpart w], [ypart w]); fi endfor
  389.   for w=1 th: if pair w: rnd_pr_y([xpart w], [ypart w]); fi endfor
  390.   curtx=curty=identity;
  391.   set_trans(x, set_tx, xset);
  392.   set_trans(y, set_ty, yset);
  393.   p_path' = if n=0: p_path else:
  394.               for i=1 upto n: new_seg(i)-- endfor cycle
  395.          fi;
  396.   interim autorounding := 0;
  397.   interim smoothing := 0;
  398.   if known fillwhite:
  399.      draw p_path' withpen pencircle scaled 4;     % was scaled 2
  400.   else:
  401.     begingroup save pic;               % Now fill
  402.     picture pic;
  403.     pic=currentpicture;
  404.     currentpicture:=nullpicture;
  405.     interim turningcheck := 0;
  406.     fill p_path';
  407.     cull currentpicture dropping origin;
  408.     addto currentpicture also pic;
  409.     endgroup;
  410.   fi
  411. enddef;
  412.