% do uverejneni clanku o INCPIC.TEX v TeX bulletinu mohou podlehat makra
% INCPIC.MF a INCPIC.TEX vyvojovym zmenam. Jakekoliv chyby, ktere se
% vyskytnou, mi laskave sdelte. Dekuji
%
% Macro for drawing simple pictures in METAFONT
% For each character the width and height is given also in user's units.
% All points are expressed in user's unit (without length units).
% For more comment see end of this file.
% Detail description appeared (in Czech) in TeXbulletin 1992, No 2,3
%
%     Prague, July 29, 1992                      Oldrich Ulrych
%                                   Mathematical institute of Charles University
%                                   email: oulrych@cspguk11.bitnet
%
%  new definition for screen window
%
def openit = openwindow currentwindow
  from origin to (640,480) at (-50,350); enddef;
%
% neither mesh nor rounding box are generated by default
%
showmesh:=0;          % don't show given mesh
showbox:=0;           % don't make box around
ou_showmesh:=0;
ou_showbox:=0;
%
% private mode for intial suggestion of pictures;
%
mode_def ouproof =
 proofing:=2;         % yes, we're making full proofs
 fontmaking:=0;       % no, we're not making a font
 tracingtitles:=1;    % yes, show titles online
 pixels_per_inch:=100;% original is that's 36 pixels per pt
 blacker:=0;          % no additional blackness
 fillin:=0;           % no compensation for fillin
 o_correction:=1;     % no reduction in overshoot
 showmesh:=1;         % show given mesh
 showbox:=1;          % make box around
 ou_showmesh:=1;
 ou_showbox:=1;
 enddef;
%
%  choosing the mode
%
if unknown mode: mode=ouproof; fi  % selection of private mode for proofing
%
% redefined beginch and endch for plotting pictures
%
def beginch(expr c,            % code of character
            w_sharp,           % sharp width
            h_sharp,           % sharp height
            d_sharp,           % sharp depth
            number_of_xunits,  % width of char in user's units
            number_of_yunits)= % height of char in user's units
 begingroup
 transform end_of_beginch;
 charcode:=if known c: byte c else: 0 fi;
 charwd:=w_sharp;      charht:=h_sharp;       chardp:=d_sharp;    charic:=0;
 w:=hround(charwd*hppp); h:=vround(charht*hppp); d:=vround(chardp*hppp);
 fontdimen byte c-63 : w_sharp/number_of_xunits;   %% measure of x-unit
 fontdimen byte c-43 : h_sharp/number_of_yunits;   %% measure of y-unit
 x_unit:=w/number_of_xunits;  nx_unit:=number_of_xunits; % auxiliary  x-unit
 y_unit:=h/number_of_yunits;  ny_unit:=number_of_yunits; % auxiliary  y-unit
 w:=number_of_xunits;    h:=number_of_yunits;
 d:=h*d_sharp/h_sharp;
 charic:=0; clearxy; clearit; clearpen; scantokens extra_beginchar;
 aux_sx:=x_unit;  aux_sy:=y_unit;
 currenttransform:=identity xscaled aux_sx yscaled aux_sy;
 shiftorigin(0,0);
 end_of_beginch:=currenttransform;
 enddef;
%
def endch =
 currenttransform:=end_of_beginch;
 gl_showmesh:=showmesh;
 gl_showbox :=showbox;
 showmesh:=ou_showmesh;
 showbox :=ou_showbox;
 if proofing>0: makebox(proofrule); fi              % I don't like rules
 if gl_showmesh>0: mesh; fi                         % show given mesh
 if gl_showbox>0: roundingbox; fi                   % make box around
 chardx:=w;     % desired width of the character in pixels
 charic:=orig_x_shift*charwd/nx_unit;
 if orig_x_shift<>0: fontdimen charcode-23 : orig_y_shift*charht/ny_unit; fi;
 scantokens extra_endchar;
 shipit;
 if displaying>0: showit;  fi
 endgroup enddef;
%
% macros used in endch;
%
def roundingbox =
   pickup pencircle scaled 0.4pt;
   draw(0,-d)--(w,-d)--(w,h)--(0,h)--(0,-d);
   draw(0,0)--(w,0);
   enddef;
def mesh =
   pickup pencircle scaled 0.4pt;
   for i=0 step 1 until w: draw (i,-d)--(i,h); endfor;
   for i=0 step 1 until h: draw (0,i)--(w,i); endfor;
   if d>0: for i=0 step 1 until d: draw (0,-i)--(w,-i); endfor; fi;
   enddef;
%
% macro for shift of user's origin
%
def shiftorigin(expr x,y) =
   orig_x_shift:=x;   orig_y_shift:=y;
   currenttransform:=currenttransform shifted
            (-orig_x_shift*aux_sx,-orig_y_shift*aux_sy);
enddef;
%
%  path for plotting arrow and axes;
%
path sharparrow;
sharparrow:=(-3,1)..{right}(0,0)&(0,0){left}..(-3,-1);
def axes expr bod =
  draw (0+orig_x_shift,ypart bod)--(w+orig_x_shift,+ypart bod);
  draw (xpart bod,-d+orig_y_shift)--(xpart bod,h+orig_y_shift);
  filldraw arrow(hround(3mm#*hppp),90) shifted (xpart bod,h+orig_y_shift);
  filldraw arrow(hround(3mm#*hppp), 0) shifted (w+orig_x_shift,ypart bod);
enddef;
def vector(expr poc,kon) =
  draw poc--kon;
  filldraw arrow(hround(2mm#*hppp),angle(kon-poc)) shifted kon;
enddef;
def arrow (expr delka, smer)=
   begingroup turningcheck:=0;
   ((-delka,-2/7delka){dir45}..{right}(0,0)&(0,0){left}..{dir135}
    (-delka, 2/7delka)&(-delka, 2/7delka)..controls (-3/4delka,0)..cycle)
       rotated smer xscaled (1/aux_sx) yscaled (1/aux_sy)
   endgroup
enddef;
%
%  macro for dotted and dashed lines
%
s__r:=10;
def add_slen(expr a,b) =
    s__x:=(xpart(b)-xpart(a))*x_unit/(hppp*s__r);
    s__y:=(ypart(b)-ypart(a))*y_unit/(hppp*s__r);
    s__:=s__+length((s__x,s__y));
enddef;
def cerchovane (expr a,b)=
   s__:=0;   add_slen(a,b);
   ju:=round(s__);
   for i=1 upto ju:
     t1:=(2*i-2)/(2*ju-1);
     t2:=(2*i-1)/(2*ju-1);
     draw t1[a,b]--t2[a,b];
     t1:=(2*i)/(2*ju-1);
     if i<ju: drawdot (0.5t1+0.5t2)[a,b]; fi;
   endfor;
   enddef;
def dashed(expr a,b)=
   s__:=0;   add_slen(a,b);
   ju:=round(s__);
   for i=4 step 4 until 4*ju:
     t1:=i/(4*ju);  t2:=(i-1)/(4*ju);  t3:=(i-3)/(4*ju);  t4:=(i-4)/(4*ju);
     draw t1[a,b]--t2[a,b];            draw t3[a,b]--t4[a,b];
   endfor;
   enddef;
eps_:=0.001;         len_given:=1;
def dashedpath expr g_path =
  p_count:=length(g_path);
  t_left:=0; t_right:=0.1p_count;
  forever:   pair aa_;  aa_=point t_left of g_path;
    forever:
      t_middlea:=1/4[t_left,t_right];   t_middleb:=3/4[t_left,t_right];
      pair ab_,ac_,ad_;
      ab_=point t_middlea of g_path;
      ac_=point t_middleb of g_path;    ad_=point t_right of g_path;
      s__:=0; add_slen(aa_,ab_); add_slen(ab_,ac_);  add_slen(ac_,ad_);
      len_dash:=s__;
      exitunless (abs(len_dash-len_given)>eps_);
      exitunless (t_right<p_count);
      len_dash:=len_given/len_dash;
      t_right:=len_dash[t_left,t_right];
      if (t_right>p_count): t_right:=p_count; fi;
    endfor;
    tenkepero;
    draw subpath (t_left,t_middlea) of g_path;
    draw subpath (t_middleb,t_right) of g_path;
    last_dif:=t_right-t_left;
    t_left:=t_right;
    exitunless (t_right<p_count);
    t_right:=t_left+last_dif;
    if (t_right>p_count): t_right:=p_count; fi;
  endfor;
enddef;
%
%  various pens
%
def penfordots = pickup pencircle scaled 10thinestline; enddef;
def thickpen  = pickup pencircle scaled 4thinestline; enddef;
def middlepen = pickup pencircle scaled 2thinestline; enddef;
def thinpen    = pickup pencircle scaled  thinestline; enddef;
def drawdots (text t) = for $=t: drawdot $; endfor; enddef;
def cdrawdot expr bod =
  drawdot bod;  pickup currentpen scaled 2/3;  erase drawdot bod;
  pickup currentpen scaled 1.5;
enddef;
def cdrawdots (text t) =
  for $=t: drawdot $; endfor;
  pickup currentpen scaled 2/3;
  for $=t: erase drawdot $; endfor;
  pickup currentpen scaled 1.5;
enddef;
%
% Czech equivalents and equivalents of previous versions
%
let peronatecky=penfordots;
let peronapuntiky=penfordots;
let tenkepero=thinpen;
let strednipero=middlepen;
let tlustepero=thickpen;
let puntiky=drawdots;
let krouzek=cdrawdot;
let drawcontourdot=cdrawdot;
let drawcontourdots=cdrawdots;
let krouzky=cdrawdots;
let carkovane=dashed;
let carkovanacesta=dashedpath;
%
%  call mode_setup
%
font_size 100mm#;
mode_setup;
thinestline:=0.4pt;

%endinput;

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% The overview of the preparation of the picture is following:
% - make a chart of the picture on the paper with the regular scale.
% - put down the coordinate system (using mesh on the paper --- units
%   correspond to the mesh)
% - mark the significant points for drawing
% - put the description into the picture
% - make oblong around the picture (using the mesh on the paper)
%   in such a way that the description in the picture is included;
%   this oblong corresponds to the rounding box of the the character
%   in which the picture will be placed
% - choose the reference point (on the left side of the rounding box)
%   of the character
% - create metafont source of the chart --- besides the usual commands
%   of metafont the definitions from this package can simplify
%   the writing of metafont source (see below) and enable to transfer
%   some important information through font to the TeX document
% - place the character from the new font created into the TeX document;
%   some significant dimensions are stored in fontdimens, so they can
%   simplify the placing of the description into the picture
%
% Useful definitions from this macro package (with the context of the
% procedure described above):
%
% beginch(char,width,height,depth,x_units,y_units);  introduces the
%     created character; the parameters have the following meaning:
%     char    - code of the character (admissible values are: "A" to "I",
%           (or "A" to "S" if macro  shiftorigin  is not used))
%     width   - width of the character in sharp units (for example 20mm#)
%     height  - height of the character in sharp units
%     depth   - depth of the character in sharp units
%     x_units - width of the picture expressed in the number of the
%            "squares" of the mesh on the paper (i.e. natural number
%            just number without any units)
%     y_units - height of the character (not depth) expressed in the
%            number of the "squares" of the mesh on the paper (i.e.
%            natural number just number without any units)
%     Using this macro as the begin of the character, all points can be
%     given in the number of the "squares" of the mesh on the paper (no
%     measures are needed). (If  c  denotes code of the given character,
%     then values  width/x_units, height/y_units  are stored in the
%     fontdimen  c-63, fontdimen  c-43, respectively).
% endch;   closing command for character.
%     If before  endch  the variable  showmesh  is positive, then
%     the character contains the mesh corresponding to the mesh on the
%     paper.
%     If before  endch  the variable  showbox  is positive, then
%     the character contains the rounding box.
%     Macros beginch  and  endch  create group, so that changes
%     betweenthem are local.
% shiftorigin(x,y);   says the origin of the choosen coordinate system
%     with respect to the reference point of the character is (x,y)
%     (expressed in the "squares" of the mesh on the paper).
%     Corresponding sharp value in the vertical direction is stored
%     in the italic correction of the character. If value  x  is nonzero,
%     than the corresponding sharp value is stored in the  fontdimen  c-23
%     (see  beginch  above);
% sharparrow    is the path --- simple arrow with the tip
%      in the origin, the length of three units and width of two units,
%      it has direstion of the x-axe
% axes z;    puts the coordinate system into the picture; the
%      intersection of axes is at the point  z
% arrow (len,ang)    is the outline of the arrow with the tip
%      in the origin, with given length  len  and in given direction  ang
% vector(sta,sto);   is the vector from the point  sta  to the point  sto
% cerchovane(sta,sto);  plots dashed and dotted line from the point  sta
%       to the point  sto
% dashed(sta,sto);  plots dashed line from the point  sta to the point  sto
% dashedpath pat;   plots dashed path  pat
% penfordots;       chooses circle pen of the width diameter 10*thinestline
%                   (for the value of  thinnestline  see below);
% thinpen;          chooses circle pen of the width diameter  thinestline
% middlepen;        chooses circle pen of the width diameter  2*thinestline
% thickpen;         chooses circle pen of the width diameter  4*thinestline
% drawdots(poi);    draws dots (with choosen pen) from the list  poi  of
%                   points
% cdrawdot(poi);    draws only contour of dot at the point  poi
% cdrawdots(poi);   at each point of the list  poi  draws contour of dot
%
% Default values of some variables:
% showmesh:=0;     mesh is not shown
% showbox:=0;      rounding box is not shown
% mode=ouproof;    if no mode is specified (the output is shown on the
%                  screen and the values showmesh,  showbox  are set
%                  positive in the definition of beginch)
% eps_:=0.001;     tolerance for iterativ process when the length of the
%                  dashes is computed (in dashedpath)
% len_given:=2;    experimental value determining the length of the dashes
%                  (in dashedpath)
% s__r:=10;        experimental value determining the length of the dashes
%                  (in  dashed  and  cerchovane)
% font_size 100mm#;    no value in the picture will be greater than 1.6m
% thinestline:=0.4pt;  the thickness of the thinnest pen
%
% Czech equivalents for some macros:
% peronatecky      is the same as  penfordots
% peronapuntiky    is the same as  penfordots
% tenkepero        is the same as  thinpen
% strednipero      is the same as  middlepen
% tlustepero       is the same as  thickpen
% puntiky          is the same as  drawdots
% krouzek          is the same as  cdrawdot
% drawcontourdot   is the same as  cdrawdot
% krouzky          is the same as  cdrawdots
% drawcontourdots  is the same as  cdrawdots
% carkovane        is the same as  dashed
% carkovanacesta   is the same as  dashedline
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%