a pleasant metafont tldr

this page is under construction

metafont is instantaneously weirder and more fascinating than TeX

==================== METAFONT ====================

https://s3-us-west-2.amazonaws.com/visiblelanguage/pdf/16.1/the-concept-of-a-meta-font.pdf
http://metafont.tutorial.free.fr/downloads/mftut.pdf
https://www.win.tue.nl/~aeb/tex/mf/metafont.html
https://timeflayer.com/d/tex/metafontbook.pdf
http://www.ntg.nl/doc/tobin/mf4begin.pdf

convert to postscript type1 with "metatype1"
only produces raster fonts. lol.

plain METAFONT:
- collection of subroutines found in Appendix B
- much like TeX vs Plain TeX, except here called a "base" rather than a "format"
- "The notions of mode setup, define pixels, beginchar, penpos, and many other things found in io.mf 
   are aspects of plain METAFONT but they are not hardwired into METAFONT itself. "

operators work on:
- numerical values
  - sqrt
- pair values
- angle-related operators

values:
- numbers
  - magnitudes
    - # ('sharp' or 'true' units of measure, remain same whether are making a font at high or low resolution)
      - eg
        - pt# (one 72.27th of an inch)
        - pt (the numer of pixels that happen to correspond to a printer's point when current resolution is taken into account)
  - units
    - pt: (one 72.27th of an inch)
    - em:
    - cap(?): the height of capital letters
  - degrees
- pairs
- angles?
  - measured in degrees 
  - counterclockwise, horizontal is 0
  - can be negative
- lists?
  - maybe «1, 2, 3, 4»?

special numerical variables:
- whatever
  - when you don't care what a value is, eg, you want a point to be aligned with two other points wherever they may be:
    - «z = whatever[z1,z2]»
- epsilon
  - smallest positive value different from zero metafont can handle
  - represents the precision of calculations with metafont 
  - 1/65536
- infinity
  - not infinity
  - highest value metafont can handle without complaining
  
special pair values:
- up (0, 1)
- down (0, -1)
- left (-1, 0)
- right (1, 0)
- origin (0, 0)

numerical operations:
- sqrt n
- a**n (exponentiation)
- / (exact division)
- div (integer division)
- mod (remainder of integer division)
- abs
- max
- min
- floor
- ceiling
- round

pair operations
- length
  - eg «length(z1-z2)»
- dotprod 
  - «(a,b) dotprod (c,d)»
  - ac+db
  - perpendicular lines: «(z2 - z1) dotprod (z4 - z3) = 0»
- shifted
  - add param to vector
  - «z1 shifted s»
- scaled, xscaled, yscaled
  - param mul vector
  - «z1 scaled s», along with rest of transformations
- rotated
  - rotate around origin by given angle
- rotatedaround
  - takes pair and angle «(z1, 90)»
- reflectedabout
  - takes two pairs
  
angle operations:
- cosd
- sind
- dir 
  - takes val as an angle, returns vector of length 1 at the angle you defined with horizontal line
- angle
  - takes vector, returns angle with horizontal

points:
- penpos«n»
- top, btm, lft, rt
- z«n»
- z«n»e

metadata:
- labels
- penlabels

cmds:
- definition
- equations/assignment (a-2b/c=0)
- showit: tries to render what you have so far in x?
- shipit: ... ? (if you are doing something without letters, sends it to the outfile?)
- end

drawing commands:
- explained more elaborately in ch14
- draw 
  - «draw z1..z2...»
  - to close a path end with cycle eg «draw z1..z2..cycle;»
  - to make straight rather than curved lines use -- eg «draw z1--z2..z3--z4..cycle;»
  - to force the angle the curve enters the point at:
    - use a builtin unit vector: «draw z1..z2..z3{left};»
    - use custom vector (doesn't need to be unit): «draw z1..z2..z3{(2,-3)}»
    - use degrees: «draw z1..z2..z3{dir -60}»
  - add "tension" to portions of a curve:
    - «draw z1..z2..tension 1.2..z3..cycle;»
    - "pulls tighter" between z2 and z3
    - default tension is 1
  - add "curl" to endpoints of a curve:
    - «draw z1{curl0}..z2..{curl2}z3..cycle;»
    - default is curl1?
    - options are curl0, curl1, curl2... ?
  - i suspected that «{left}z2» enters the point on the left and «z2{left}» leaves the point on the left
    - you cannot seem to have both though
- drawdot
- fill
- unfill
- penstroke
  - «e» stand's for pen's edge in eg «z1e»

rendering (rastering?) commands:
- define_pixels
- define_blacker_pixels
  - im not really sure
  - "The command on line 6, ‘define_blacker_pixels’, adds a correction based on the device for which the font is being
     prepared. For example, if the resolution is 3 pixels per point, the value of thin when converted from true units
     to pixels by define pixels would be 1, but define blacker pixels might set thin to a value closer to 2."
- define_corrected_pixels

point positioning:
- top
- bot
- lft
- rt

pens:
- pinkup
- putdown
- types:
  - pencircle
  - pensquare
  - penrazor
  - penspeck
- can be:
  - scaled
  - xscaled
  - yscaled
  - rotated
- penpos
  - considering a set of three points «z1, z2, z3»
  - which stands for pen's left edge, midpoint, right edge
  - so, penpos states the breadth of the pen and angle of inclination at a particular position
  - «penpos1(1.2pt, 30);» makes pen 1.2pt broad and tipped 30º at respect to horizontal
  - penpos«k»(«b»,«d»);
    - k is position number
    - b is breadth (in pixels)
    - d is angle (in degrees)
  - penpos«k»(«b»,«d») is an abbreviation for two equations:
    - z«k»=(1/2)[z«kl»,z«kr»];
    - z«kr»=z«kl»+(b,0) rotated d;
- penstroke
  - «penstroke z1e..z2e{right}..{right}z3e;» equivalent to:
  - «fill z1l..z2l{right}..{right}z3l--z3r{left}..{left}z2r..z1r--cycle;»
  - in a sense fills region «p.l -- reverse p.r -- cycle»
    - where p.l and p.r are the left and right paths formed by changing each «e» into 'l' or 'r' respectively
  

etc:
- use eg z1 to refer to (x1,y1) 
- «t[y1, y2]» equivalent to «y1 + t[y2-y1]»

filetypes
- .mf: metafont source file
- .tfm: font metrics file
- .«n»gf: glyphs file
- .«n»pk: packed glyphs file?
  - produced by GFtoPK

programs:
- gftopk
  - converts .gf type to .pk type, for use with tex
- gftype
  - validity checking?
- gftodvi
  - https://rcweb.dartmouth.edu/doc/texmf-dist/doc/generic/knuth/mfware/gftodvi.pdf
  - gray fonts
  - known specials
  - 'title'
  
internal quantities:
- https://timeflayer.com/d/tex/metafontbook.pdf#page=224
- tracing
  - tracingtitles
  - tracingequations
  - tracingcapsules
  - tracingchoices
  - tracingspecs
  - tracingpens
  - tracingcommands
  - tracingrestores
  - tracingmacros
  - tracingedges
  - tracingoutput
  - tracingonline
  - tracingstats
- interaction
  - pausing: show lines on the terminal before they are read
  - showstopping: stop after each show command
- modes
  - fontmaking: produce font metric output
  - proofing: roduce proof mode output
    - 1: unlabeled proofs
    - 2: full proofs
- etc behavior
  - turningcheck: rorient clockwise paths, flag strange ones
  - warningcheck: advice when a variable gets large
  - smoothing: remove certain glitches from digitized curves
  - autorounding: move paths to "good" tangent points
  - granularity: the pixel size for autorounding
  - fillin: the extra darkness of diagonals (to be counteracted)
- datetime values
  - year
  - month
  - day
  - time 
- internals
  - charcode
  - charext
  - charwd
  - charht
  - charic
  - chardx
  - chardy
  - designsize
  - hppp
  - vppp
  - xoffset
  - yoffset
- ?
  - boundarychar: the right boundary character for ligatures and kerns

control flow/loops:
- for
  - has interesting macro-style behavior?? 
    - eg «for z=origin,right,up: z transformed identity = z; endfor»
- forsuffixes?
    
types:
- number
- pair
- picture
- string

macros/definitions:
- def?
- vardef?
- primary?
  - eg in «def gobble primary g = enddef;»
- primarydef?
  - eg in «primarydef g gobbled gg = enddef;»
- secondarydef
- tertiarydef
- newinternal?
  - eg in «newinternal eps,epsilon,infinity,_;»
- let

modes:
- proof mode
- smoke mode:
  - "for label-free proofs to mount on the wall"
  - proof_; proofing:=1; extra_setup:=extra_setup&"grayfont black";
  - let makebox=maketicks;enddef;
  
limitations:
- all valid numbers are strictly less than 4096
- "at most 15 different nonzero heights, 15 different nonzero depths, 63 different nonzero italic 
  corrections my appear in a single font"
- (addto) withweight only accepts values that round to +-(1, 2, 3)
  - ... but you can just use additional addtos to get around it
  
mysteries:
 - variables
   - extra_setup
   - blacker
   - fillin
   - o_correction
- clearit;
- this code:
  - vardef byte primary s =
      if string s: ASCII fi s enddef;
- this code:
  - def mode_def suffix $ =
     $:=incr number_of_modes;
     mode_name[$]:=str$ & "_";
     expandafter quote def scantokens mode_name[$] enddef;
     newinternal number_of_modes;


==================== METAPOST? ====================
https://wiki.contextgarden.net/MetaFun
mpost --mem=metafun ourfile.mp

go home