4 Interpolations and font math
(require sfont/math) | package: sfont |
With this module it is possible to perform interpolations between fonts using the idea of ’glyph math’ or ’font math’ (see Robofab glyphmath or Tal Leming’s FontMath). The idea is that glyphs can be treated like vectors defining two basic operations: sum and scalar multiplication, obviously the glyphs should be ’compatible’ (the should have the same number of points). In the same way we can extends the same abstraction with fonts (they also have to be compatible). With this idea we can perform an interpolation between two fonts in a simple way: (+ a (* (- b a) f)) where a and b are fonts and f is a number.
The operations affect not only contours but also anchors, components, and font metric informations. The operation of making two or more fonts compatible can be tedious, therefore the module define functions and macros to do this:
keep only common glyphs
transform line segments in curve segments (with control points at extrema)
sort contours and points inside contours
remove components or anchors if they are not in the corresponding glyphs
sort components and anchors
keep only common font informations
(define-interpolable-fonts (light-c light-font) (bold-c bold-font) (wide-c wide-font))
Now light-c, bold-c and wide-c are interpolables fonts.
procedure
(+ o os ...) → fontmath-object/c
o : fontmath-object/c os : fontmath-object/c
procedure
(* o os ...) → fontmath-object/c
o : fontmath-object/c os : fontmath-object/c
procedure
(- o os ...) → fontmath-object/c
o : fontmath-object/c os : fontmath-object/c
procedure
(/ o os ...) → fontmath-object/c
o : fontmath-object/c os : fontmath-object/c
value
fontmath-object/c : flat-contract?
With the mathematical abstraction we are using we can express something more than interpolations. For example we can build a bold-wide from a light a bold and a wide.
(define bold-wide (+ light-c (- bold-c light-c) (- wide-c light-c)))
To make this simpler Sfont has a macro that define an interpolation ’space’ where one can simply write:
(define bold-wide (sp1 (+ sp1-bold-c sp1-wide-c)))
(define-space sp1 (light-c [bold-c wide-c]))
This line will define a procedure sp1 and two fonts: sp1-bold-c (obtained with (- bold-c light-c)) and sp1-wide-c (obtained with (- wide-c light-c)) that can be used like the example above.
In this ’space’ the interpolations between light and bold can be expressed with
(sp1 (* sp1-bold-c 0.6))
that is equivalent to:
(+ light-c (* (- bold-c light-c) 0.6)) .
procedure
(x-> o) → geometric?
o : geometric?
procedure
(y-> o) → geometric?
o : geometric?
(sp1 (+ (* (x-> sp1-bold-c) 0.6) (* (y-> sp1-bold-c) 0.4)))
It will increase contrast.