% EUROMAC.MF --- version 3.0 (6 March 2002) --- (c) Harold W. de Wijn
% DRIVER FILE TO GENERATE EURO SYMBOLS
% FILE SHOULD BE RENAMED WHENEVER IT IS MODIFIED!


message "EUROMAC.MF v3.0 (6 March 2002) - (c) Harold W. de Wijn";

mode_setup;


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Macros
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

def draw_euro =

italcorr 0.85BoxHeight#*S;   % height of upper right corner times S

% ---------- Geometrical parameters ----------
OuterDiameter#:=BoxHeight# + 2o#;      % o_correction omitted
define_pixels(OuterDiameter);
w#:=(LeftMargin# + 0.99282*WidthFactor(C,T)*C*OuterDiameter#
      + RightMargin#);                 % cf. notes to WidthFactor below
charwd:=w#;
define_whole_pixels(w);

BarSeparation:=1/12OuterDiameter;
Thickness:=1/12OuterDiameter*T;
BarProtrusion:=(5/6cosd40 - 1/2)*OuterDiameter;

% The leftward protrusion of the bars is defined on the basis of the
% official symbol, for which, measured in the horizontal direction, the
% left end of the bars is twice as far from the circle center as the lower
% right end of the beak.

% ---------- Transformation ----------
currenttransform:=identity if C<>1: xscaled C fi if S<>0: slanted S fi
    transformed add_transform;
% The transform add_transform may provide additional transformations,
% such as reflections and rotations.

% ---------- Pen ----------
pickup pencircle scaled Thickness;

% ---------- Circle ----------
Left:=LeftMargin/C + BarProtrusion;  % abscissa of circle's leftmost edge
z1=(Left + 1/2Thickness/C, 1/2h);
z0=z1 + (good.y(1/2OuterDiameter - 1/2Thickness + 1/2h) - 1/2h, 0);
forsuffixes $=2,3,4,5,6,7,8: z$=z1 rotatedaround(z0,45*($-1)); endfor;

% To lessen the risk of pimples at the horizontal tangents, the circle's
% center point z0 is positioned at such a distance from z1 that z3 and z7
% have "good" y values.

draw z1{down}..z2{down+right}..z3{right}..z4{right+up}..z5{up}..
   z6{up+left}..z7{left}..z8{left+down}..cycle;

% ---------- Defining beak ----------
% The beak of the official euro symbol is defined by the point where the
% radius at 40 degrees from horizontal meets the circle.  We rather use
% the equivalent definition that the median of the circle, i.e., the path
% traversed by the pen, ends at 42.6717 degrees (z31).

z31=z1 rotatedaround(z0,-180+42.6717);
z32=(x3,y3-1/2Thickness);
z33=whatever[z32,z31];
x33=x31 - OuterDiameter*(0.01780       % so far the official geometry
   + 0.01780*(T-1) + 0.005*(C-1) - 0.004*S + 0.003*(C-1)*(C-1)
   + 0.002*(C-1)*(T-1))/C;             % cf. notes to WidthFactor below

% ---------- Cross bars ----------
z40=(round(Left-BarProtrusion),y41+pen_bot);
z50=(x40,y51+pen_bot);
extra_pixel_x:=1;
z41=(x40 + (min(pen_bot*S,pen_top*S) - extra_pixel_x)/C,
       good.y(y0 + 1/2BarSeparation + 1/2Thickness));
z42=(x33 + (max(pen_bot*S,pen_top*S) + extra_pixel_x)/C,y41);
z51=(x41, good.y(y0 - 1/2BarSeparation - 1/2Thickness));
z52-z42=whatever*(z31-z32); y52=y51;

% The median heights y41 and y51 of the cross bars have "good" values
% and the abscissae x40 and x50 of the left ends are rounded to integers
% for the sake of uniformity at low resolution.

draw z41--z42;
draw z51--z52;

% ---------- Erasing excess ----------
% One extra pixel is added to be on the safe side.  Note that sloped
% tangents to the pen circle are horizontally displaced from the pen's
% center by sqrt(1+S**2) times the radius.  Instead of the square root,
% we rely on the more efficient function 1+abs(S), which is equal or
% larger.  We however first normalize the current picture, because
% regions where bars and circle overlap and possibly some pixels near
% z1 to z8 have double weight.

cull currentpicture keeping (1,infinity) withweight 1;

extra_pixel_x:=1; extra_pixel_y:=1;
z61=(x5 + (pen_rt + max(pen_top*S,pen_bot*S) + extra_pixel_x)/C,y7);
z62=whatever[z32,z31]; y62=y7;
z63=whatever[z32,z31]; y63=y51+pen_bot-extra_pixel_y;
z64=(x33,y63);
z65=(x64,y32);
z66=(x61,y32);
unfill z61--z62--z63--z64--z65--z66--cycle;

z71-z40=whatever*(z32-z31); y71=y41+pen_top+extra_pixel_y;
z72=(x41 + (pen_lft + min(pen_bot*S,pen_top*S) - extra_pixel_x)/C,y71);
z73=(x72,y74);
z74-z40=whatever*(z32-z31); y74=y41+pen_bot-extra_pixel_y;
unfill z71--z72--z73--z74--cycle;

z75-z50=whatever*(z32-z31); y75=y51+pen_top+extra_pixel_y;
z76=(x72,y75);
z77=(x72,y78);
z78-z50=whatever*(z32-z31); y78=y51+pen_bot-extra_pixel_y;
unfill z75--z76--z77--z78--cycle;

% ---------- Pen labels ----------
penlabels(0,1,2,3,4,5,6,7,8,31,32,33,40,41,42,50,51,52,
   61,62,63,64,65,66,71,72,73,74,75,76,77,78);

enddef;

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

def WidthFactor(expr C,T) =
% The overall width of the official euro symbol, i.e., the horizontal
% distance between the left end of the bars and the upper outer corner of
% the beak, amounts to
%    (5/6cosd40 + 1/2sind(2angle(5cosd40,6+5sind40))) = 0.99282
% times the outer diameter.  Transformations while keeping the pen nib
% invariant as well as changing the thickness displace these end points
% from their "official" positions.  The associated corrections to the
% width are to sufficient accuracy approximated by the factor
     (1 - (0.017*(T-1) + 0.051*(C-1) + 0.004*S + 0.068*(C-1)*(T-1))/C)
enddef;

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

def makebox(text r) =
for y=0,1/2h,h: r((y*S,y),(w+y*S,y)); endfor;
for x=0,LeftMargin,w-RightMargin,w:
  if S=0: r((x,0),(x,h));
  else: for y=0,1/2h,h: r((x+y*S,y-0.01h),(x+y*S,y+0.01h)); endfor; fi;
endfor;
if S>0: r((w+charic*pt,3/4h),(w+charic*pt,h+o)); fi;
enddef;

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

def outline =      % cf. The METAFONTbook, p.244
cull currentpicture keeping (1,infinity) withweight 1;
picture v; v:=currentpicture;
cull currentpicture keeping (1,1) withweight 3;
addto currentpicture also v
   -v shifted right -v shifted left -v shifted up -v shifted down;
cull currentpicture keeping (1,4);
enddef;


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Generating symbols
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% ---------- Defaults, pixels ----------
LeftMargin#:=20/36pt#; RightMargin#:=20/36pt#;   % universal values
define_pixels(LeftMargin,RightMargin,o);

if unknown C: C:=1; fi;      % no condensing is default
if unknown S: S:=0; fi;      % no slanting is default
if unknown T: T:=1; fi;      % official thickness is default

transform add_transform; def add_transform = identity enddef;

% ---------- Return to calling file? ----------
% Now generate the font unless you wish to return to the calling file.
if unknown Return: relax elseif Return=1: endinput; fi;

% ---------- Font dimensions ----------
font_slant S;
font_x_height x_height#;
font_normal_space 6u#+2letter_fit#;
font_normal_stretch 3u#;
font_normal_shrink 2u#;
font_quad 18u#+4letter_fit#;
font_extra_space 2u#;

% ---------- Euro as high as capital C ----------
BoxHeight#:=cap_height#;     % width of box is computed by draw_euro

C:=1;
"Official euro symbol (cap height)";
beginchar("E",0,BoxHeight#,0); draw_euro; endchar;
"Official euro symbol (cap height outline)";
beginchar("O",0,BoxHeight#,0); draw_euro; outline; endchar;

C:=0.887;   % golden section**(1/4)
"Demicondensed (cap height)";
beginchar("D",0,BoxHeight#,0); draw_euro; endchar;
"Demicondensed (cap height outline)";
beginchar("N",0,BoxHeight#,0); draw_euro; outline; endchar;

C:=0.786;   % square root of golden section
"Condensed (cap height)";
beginchar("F",0,BoxHeight#,0); draw_euro; endchar;
"Condensed (cap height outline)";
beginchar("P",0,BoxHeight#,0); draw_euro; outline; endchar;

C:=0.618;   % golden section
"Double condensed (cap height)";
beginchar("G",0,BoxHeight#,0); draw_euro; endchar;
"Double condensed (cap height outline)";
beginchar("Q",0,BoxHeight#,0); draw_euro; outline; endchar;

% ---------- Euro as high as numerals ----------
BoxHeight#:=fig_height#;

C:=1;
"Official euro symbol (fig height)";
beginchar("e",0,BoxHeight#,0); draw_euro; endchar;
"Official euro symbol (fig height outline)";
beginchar("o",0,BoxHeight#,0); draw_euro; outline; endchar;

C:=0.887;   % golden section**(1/4)
"Demicondensed (fig height)";
beginchar("d",0,BoxHeight#,0); draw_euro; endchar;
"Demicondensed (fig height outline)";
beginchar("n",0,BoxHeight#,0); draw_euro; outline; endchar;

C:=0.786;   % square root of golden section
"Condensed (fig height)";
beginchar("f",0,BoxHeight#,0); draw_euro; endchar;
"Condensed (fig height outline)";
beginchar("p",0,BoxHeight#,0); draw_euro; outline; endchar;

C:=0.618;   % golden section
"Double condensed (fig height)";
beginchar("g",0,BoxHeight#,0); draw_euro; endchar;
"Double condensed (fig height outline)";
beginchar("q",0,BoxHeight#,0); draw_euro; outline; endchar;

bye

