summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/doc/context/sources/general/manuals/evenmore/evenmore-threesix.tex
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/doc/context/sources/general/manuals/evenmore/evenmore-threesix.tex')
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/evenmore/evenmore-threesix.tex739
1 files changed, 739 insertions, 0 deletions
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/evenmore/evenmore-threesix.tex b/Master/texmf-dist/doc/context/sources/general/manuals/evenmore/evenmore-threesix.tex
new file mode 100644
index 00000000000..d75f9b68396
--- /dev/null
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/evenmore/evenmore-threesix.tex
@@ -0,0 +1,739 @@
+% language=us
+
+\environment evenmore-style
+
+\useMPlibrary[threesix]
+
+\startcomponent evenmore-threesix
+
+\startchapter[title={ThreeSix, Don Knuths first colorfont?}]
+
+In the process of reaching completion and perfection Don Knuth occasionally posts
+links to upcoming parts of the TAOCP series on his web pages. Now, I admit that
+much is way beyond me but I do understand (and like) the graphics and I know that
+Don uses \METAPOST. The next example code is just a proof of concept but might
+eventually become a decent module (with helpers) for making (runtime) fonts.
+After all, we need to adapt to current developments and \TEX ies always are
+willing to adapt and experiment. This chapter was written at the same time as
+the previous one on \TYPETHREE\ fonts so you might want to read that first.
+
+The font explored here is \type {FONT36}, used in \quotation {A potpourri of
+puzzles} and flagged as \quotation {a special font designed for dissection
+puzzles} (in fascicle 9b for Volume 4). Playing with and visualizing for me often
+works better than formulas, which then distracts me from the original purpose,
+but let's have a closer look anyway.
+
+\startlinecorrection
+ \scale[width=\textwidth]{\DEKFontA 1234567890} \vskip1ex
+ \scale[width=\textwidth]{\DEKFontA ABC{\red DE}FGHIJ{\red K}LM} \vskip1ex
+ \scale[width=\textwidth]{\DEKFontA NOPQRSTUVWXYZ}
+\stoplinecorrection
+
+The font has a fixed maximum height of 8~quantities. There is no depth in the
+characters. Some characters are wider. In this example we use a tight bounding
+box. In \CONTEXT\ speak this font is just a regular font but with a special
+feature enabled.
+
+\starttyping
+\definefontfeature
+ [fontthreesix]
+ [default]
+ [metapost=fontthreesix]
+
+\definefont[DEKFontA][Serif*fontthreesix]
+\stoptyping
+
+After this the \type {\DEKFontA} command will set this font as current font. The
+definition mentions \type {Serif} as font name. In \CONTEXT\ this name will
+resolve in the currently defined Serif, so when your document uses Latin Modern
+that will be the one. The \type {fontthreesix} will make this instance use that
+feature set, and the feature definition has the defaults as parent (so we get
+kerning, ligatures, etc.) but as extra feature also \type {metapost}. This means
+that the new glyphs that are about to be defined will actually be injected in the
+\type {Serif}! We will replace characters in that instance. So, the following:
+
+\startbuffer[taocp]
+This font is used in \quotation {The Art Of Computer Programming} by
+Don Knuth, not in volume~1, 2 or~3, but in number~4!
+\stopbuffer
+
+\typebuffer[taocp]
+
+comes out as:
+
+\startnarrower
+\DEKFontA \getbuffer[taocp]
+\stopnarrower
+
+But that doesn't look too good, so we will tweak the font a bit:
+
+\starttyping
+\definefontfeature
+ [fontthreesix-color]
+ [default]
+ [metapost={category=fontthreesix,spread=.1}]
+
+\definefont[DEKFontD][Serif*fontthreesix]
+\stoptyping
+
+The \type {spread} (multiplied by the font unit, which is 12 basepoints here)
+will add a bit more spacing around the blob:
+
+\startnarrower
+\DEKFontD \getbuffer[taocp]
+\stopnarrower
+
+Now, keep in mind that we're talking of a real font here. You can cut and paste
+these characters. It's just the default uppercase Latin alphabet plus digits.
+
+Before we go and look at some of the code needed to render this, a few more
+examples will be given.
+
+\startlinecorrection
+ \scale[width=\textwidth]{\DEKFontB 1234567890} \vskip4pt
+ \scale[width=\textwidth]{\DEKFontB ABCDEFGHIJKLM} \vskip4pt
+ \scale[width=\textwidth]{\DEKFontB NOPQRSTUVWXYZ}
+\stoplinecorrection
+
+In the above example we not only use color, but also a different shape and random
+colors (that is: random per \TEX\ job). The feature definition for this is:
+
+\starttyping
+\definefontfeature
+ [fontthreesix-color]
+ [default]
+ [metapost={%
+ category=fontthreesix,shape=diamond,%
+ color=random,pen=fancy,spread=.1%
+ }]
+\stoptyping
+
+Possible shapes are \type {circle}, \type {diamond} and \type {square} and
+instead of a random color one can give a known color name. Using transparency
+makes no sense in this font.
+
+A nice usage for this font are initials: % 4 for lm
+
+\startbuffer
+\setupinitial[font=Serif*fontthreesix-initial sa 5]
+{\DEKFontB \placeinitial \input zapf\par}
+\stopbuffer
+
+\typebuffer
+
+The initial feature is defined as:
+
+\starttyping
+\definefontfeature
+ [fontthreesix-initial]
+ [metapost={category=fontthreesix,color=random,shape=circle}]
+\stoptyping
+
+We use this in quoting Hermann Zapf, one that for sure is very applicable in
+a case like this:
+
+\startnarrower
+\getbuffer
+\stopnarrower
+
+Some combinations of sub|-|features are shown in \in {figure} [threesix:dek]. We
+blow up the diamond with fancy pen example in \in {figure} [threesix:tex]. Alas,
+the \TEX\ logo doesn't look that good in such a font. Using it for acronyms is
+not a good idea anyway, but maybe you can figure out \in {figure}
+[threesix:taocp].
+
+% todo penx peny penr
+
+\definefontfeature
+ [fontthreesix-circle]
+ [metapost={category=fontthreesix,shape=circle,color=random}]
+\definefontfeature
+ [fontthreesix-square]
+ [metapost={category=fontthreesix,shape=square,color=random}]
+\definefontfeature
+ [fontthreesix-diamond]
+ [metapost={category=fontthreesix,shape=diamond,color=random}]
+\definefontfeature
+ [fontthreesix-circle-pen]
+ [metapost={category=fontthreesix,shape=circle,color=random,pen=fancy}]
+\definefontfeature
+ [fontthreesix-square-pen]
+ [metapost={category=fontthreesix,shape=square,color=random,pen=fancy}]
+\definefontfeature
+ [fontthreesix-diamond-pen]
+ [metapost={category=fontthreesix,shape=diamond,color=random,pen=fancy}]
+\definefontfeature
+ [fontthreesix-circle-random]
+ [metapost={category=fontthreesix,random=yes,shape=circle,color=random}]
+\definefontfeature
+ [fontthreesix-square-random]
+ [metapost={category=fontthreesix,random=yes,shape=square,color=random}]
+\definefontfeature
+ [fontthreesix-diamond-random]
+ [metapost={category=fontthreesix,random=yes,shape=diamond,color=random}]
+
+\definefontfeature
+ [fontthreesix-circle-random-spread]
+ [metapost={category=fontthreesix,random=yes,shape=circle,color=random,spread=.1}]
+
+\startplacefigure[reference=threesix:dek]
+ \startcombination[3*3]
+ {\scale[width=.3\textwidth]{\definedfont [Serif*fontthreesix-circle]D\kern1pt E\kern 1ptK}} {\type{shape=circle}}
+ {\scale[width=.3\textwidth]{\definedfont [Serif*fontthreesix-square]D\kern1pt E\kern 1ptK}} {\type{shape=square}}
+ {\scale[width=.3\textwidth]{\definedfont [Serif*fontthreesix-diamond]D\kern1pt E\kern 1ptK}} {\type{shape=diamond}}
+ {\scale[width=.3\textwidth]{\definedfont [Serif*fontthreesix-circle-pen]D\kern1pt E\kern 1ptK}} {\type{shape=circle,pen=fancy}}
+ {\scale[width=.3\textwidth]{\definedfont [Serif*fontthreesix-square-pen]D\kern1pt E\kern 1ptK}} {\type{shape=square,pen=fancy}}
+ {\scale[width=.3\textwidth]{\definedfont [Serif*fontthreesix-diamond-pen]D\kern1pt E\kern 1ptK}} {\type{shape=diamond,pen=fancy}}
+ {\scale[width=.3\textwidth]{\definedfont [Serif*fontthreesix-circle-random]D\kern1pt E\kern 1ptK}} {\type{shape=circle,random=yes}}
+ {\scale[width=.3\textwidth]{\definedfont [Serif*fontthreesix-square-random]D\kern1pt E\kern 1ptK}} {\type{shape=square,random=yes}}
+ {\scale[width=.3\textwidth]{\definedfont[Serif*fontthreesix-diamond-random]D\kern1pt E\kern 1ptK}} {\type{shape=diamond,random=yes}}
+ \stopcombination
+\stopplacefigure
+
+\startplacefigure[reference=threesix:tex]
+\scale[width=\textwidth]{\definedfont[Serif*fontthreesix-diamond-pen]T\lower.5ex\hbox spread .1em{\hss E\hss}X}
+\stopplacefigure
+
+\startplacefigure[reference=threesix:taocp]
+\scale[width=\textwidth]{\definedfont[Serif*fontthreesix-circle-random-spread]TAOCP}
+\stopplacefigure
+
+You can quit reading now or expose yourself to how this is coded. We use a
+combination of \LUA\ and \METAPOST, but different solutions are possible. The
+shapes are entered (or course) with zeros and ones.
+
+\starttyping
+\startluacode
+local font36 = {
+ ["0"] = "00111100 01111110 11000011 11000011 11000011 ...",
+ ["1"] = "00011100 11111100 11101100 00001100 00001100 ...",
+ .....
+ ["D"] = "11111100 11100010 01100011 01100011 01100011 ...",
+ ["E"] = "1111111 1110001 0110101 0111100 0110100 0110001 ...",
+ .....
+ ["K"] = "11101110 11100100 01101000 01110000 01111000 ...",
+ .....
+}
+\stopluacode
+\stoptyping
+
+We also use \LUA\ to register this font. The actual code looks slightly different
+because it uses some helpers from the \CONTEXT\ \LUA\ libraries. We remap the
+bits pattern onto \METAPOST\ macro calls.
+
+\starttyping
+\startluacode
+local replace = {
+ ["0"] = "N;",
+ ["1"] = "Y;",
+ [" "] = "L;",
+}
+
+function MP.registerthreesix(name)
+ fonts.dropins.registerglyphs {
+ name = name,
+ units = 12,
+ usecolor = true,
+ }
+ for u, v in table.sortedhash(font36) do
+ local ny = 8
+ local nx = (#v - ny + 1) // ny
+ local height = ny * 1.1 - 0.1
+ local width = nx * 1.1 - 0.1
+ local code = string.gsub(v,".",replace)
+ fonts.dropins.registerglyph {
+ category = name,
+ unicode = utf.byte(u),
+ width = width,
+ height = height,
+ code = string.format("ThreeSix(%s);",code),
+ }
+ end
+end
+
+MP.registerthreesix("fontthreesix")
+\stopluacode
+\stoptyping
+
+So, after this the font \type {fontthreesix} is known to the system but we still
+need to provide \METAPOST\ code to generate it. The glyphs themselves are now
+just sequences of \type {N}, \type {Y} and \type {L} with some wrapper code
+around it. The definitions are put in the \type {MP} namespace simply because a
+first version initialized in \METAPOST, and there could create variants, but in
+the end I settled on the parameter interface at the \TEX\ end.
+
+The next definition looks a bit complex but normally such a macro is
+stepwise constructed. Notice how we can query the sub features. In order to make
+that possible the regular \METAFUN\ parameter handling code is used. We just push
+the sub|-|features into to \type {mpsfont} namespace.
+
+\starttyping
+\startMPcalculation{simplefun}
+
+def InitializeThreeSix =
+ save Y, N, L, S ; save dx, dy, nx, ny ; save currentpen ;
+ save shape, fillcolor, mypen, random, spread, hoffset ;
+ string shape, fillcolor, mypen ; boolean random ;
+ pen currentpen ;
+ dx := 11/10 ;
+ dy := - 11/10 ;
+ nx := - dx ;
+ ny := 0 ;
+ shape := getparameterdefault "mpsfont" "shape" "circle" ;
+ random := hasoption "mpsfont" "random" "true" ;
+ fillcolor := getparameterdefault "mpsfont" "color" "" ;
+ mypen := getparameterdefault "mpsfont" "pen" "" ;
+ spread := getparameterdefault "mpsfont" "spread" 0 ;
+ hoffset := 12 * spread / 2 ;
+ currentpen := pencircle
+ if mypen = "fancy" :
+ xscaled 1/20 yscaled 2/20 rotated 45
+ else :
+ scaled 1/20
+ fi ;
+ if shape == "square" :
+ def S =
+ unitsquare if random : randomized 1/10 fi
+ shifted (nx,ny)
+ enddef ;
+ elseif shape = "diamond" :
+ def S =
+ unitdiamond if random : randomized 1/10 fi
+ shifted (nx,ny)
+ enddef ;
+ else :
+ def S =
+ unitcircle if random : randomizedcontrols 1/20 fi
+ shifted (nx,ny)
+ enddef ;
+ fi ;
+ def N =
+ nx := nx + dx ;
+ draw S ;
+ enddef ;
+ if fillcolor = "random" :
+ def Y =
+ nx := nx + dx ;
+ fillup S withcolor white randomized (2/3,2/3,2/3) ;
+ enddef ;
+ elseif fillcolor = "" :
+ def Y =
+ nx := nx + dx ;
+ fillup S ;
+ enddef ;
+ else :
+ def Y =
+ nx := nx + dx ;
+ fillup S withcolor fillcolor ;
+ enddef ;
+ fi ;
+ def L =
+ nx := - dx ;
+ ny := ny + dy ;
+ enddef ;
+enddef ;
+
+vardef ThreeSix (text code) =
+ InitializeThreeSix ; % todo: once per instance run
+ draw image (code) shifted (hoffset,-ny) ;
+enddef ;
+
+\stopMPcalculation
+\stoptyping
+
+This code is not that efficient in the sense that there's quite some
+\METAPOST|-|\LUA|-|\METAPOST\ traffic going on, for instance each parameter check
+involves this, but in practice performance is quite okay, certainly for such a
+small font. There will be an initializer option some day soon. The \type
+{simplefun} is a reference to an \MPLIB\ instance that does load \METAFUN\ but
+only the modules that make no sense for this kind of usage. It also enforces
+double mode. The calculations wrapper just executes the code and does not place
+some (otherwise empty) graphic.
+
+% After playing with the font I see the beauty of the descriptions in the
+% pre|-|fascicle 9b but I still feel pretty stupid. Lucky for me there are
+% exercises like 999, tagged as \quote {for dummies}, so I'm not alone.
+
+Those who have seen (and|/|or read) \quotation {Concrete Mathematics} will have
+noticed the use of inline images, like dice. Dice are also used in \quotation
+{pre-fascicle 5a} (I need a few more lives to grasp that, so I stick to the
+images for now!). So, to compensate the somewhat complex code above, I will show
+how to accomplish that. This time we do all in \METAPOST:
+
+\startMPcalculation{simplefun}
+
+def DiceFrame =
+ pickup pencircle scaled 1/2 ;
+ draw unitsquare scaled 8 ;
+ pickup pencircle scaled 3/2 ;
+enddef ;
+
+vardef DiceOne =
+ DiceFrame ;
+ draw (4,4) ;
+enddef ;
+vardef DiceTwoA =
+ DiceFrame ;
+ draw (2,6) ; draw (6,2) ;
+enddef ;
+vardef DiceTwoB =
+ DiceFrame ;
+ draw (6,6) ; draw (2,2) ;
+enddef ;
+vardef DiceTwo =
+ if hasoption "mpsfont" "option" "reverse" :
+ DiceTwoB
+ else :
+ DiceTwoA
+ fi ;
+enddef ;
+vardef DiceThreeA =
+ DiceFrame ;
+ draw (2,6) ; draw (4,4) ; draw (6,2) ;
+enddef ;
+vardef DiceThreeB =
+ DiceFrame ;
+ draw (6,6) ; draw (4,4) ; draw (2,2) ;
+enddef ;
+vardef DiceThree =
+ if hasoption "mpsfont" "option" "reverse" :
+ DiceThreeB
+ else :
+ DiceThreeA
+ fi ;
+enddef ;
+vardef DiceFour =
+ DiceFrame ;
+ draw (2,6) ; draw (6,6) ; draw (2,2) ; draw (6,2) ;
+enddef ;
+vardef DiceFive =
+ DiceFrame ;
+ draw (2,6) ; draw (6,6) ; draw (4,4) ; draw (2,2) ; draw (6,2) ;
+enddef ;
+vardef DiceSix =
+ DiceFrame ;
+ draw (2,6) ; draw (6,6) ; draw (2,4) ; draw (6,4) ; draw (2,2) ; draw (6,2) ;
+enddef ;
+
+vardef DiceBad =
+ pickup pencircle scaled 1/2 ;
+ draw unitsquare scaled 8 ;
+ draw (1,7) -- (7,1) ; draw (1,1) -- (7,7) ;
+enddef ;
+
+lmt_registerglyphs [
+ name = "dice",
+ units = 12,
+ width = 8,
+ height = 8,
+ depth = 0,
+ usecolor = true,
+] ;
+
+lmt_registerglyph [ category = "dice", unicode = "0x2680", code = "DiceOne;" ] ;
+lmt_registerglyph [ category = "dice", unicode = "0x2681", code = "DiceTwo;" ] ;
+lmt_registerglyph [ category = "dice", unicode = "0x2682", code = "DiceThree;" ] ;
+lmt_registerglyph [ category = "dice", unicode = "0x2683", code = "DiceFour;" ] ;
+lmt_registerglyph [ category = "dice", unicode = "0x2684", code = "DiceFive;" ] ;
+lmt_registerglyph [ category = "dice", unicode = "0x2685", code = "DiceSix;" ] ;
+
+lmt_registerglyph [ category = "dice", private = "invaliddice", code = "DiceBad;" ] ;
+
+\stopMPcalculation
+
+This is not that hard to follow. We define some shapes first. These could have
+been assigned to the \type {code} parameter directly but this is nicer. Next we
+register the font itself and after that we set glyphs. We also set the official
+\UNICODE\ slots. So, copying a dice can either result in a digit or in a
+\UNICODE\ slot for a dice. In the example below we switch to a color which
+demonstrates that our dice can be colored at the \TEX\ end. It's either that or
+coloring at the \METAPOST\ end as both demand a different kind of \TYPETHREE\
+embedding trickery.
+
+We actually predefine three features. The digits one will map regular digit in
+the input to dice. We accomplish that via a font feature:
+
+\startbuffer
+\startluacode
+fonts.handlers.otf.addfeature("dice:digits", {
+ type = "substitution",
+ order = { "dice:digits" },
+ nocheck = true,
+ data = {
+ [0x30] = "invaliddice",
+ [0x31] = 0x2680,
+ [0x32] = 0x2681,
+ [0x33] = 0x2682,
+ [0x34] = 0x2683,
+ [0x35] = 0x2684,
+ [0x36] = 0x2685,
+ [0x37] = "invaliddice",
+ [0x38] = "invaliddice",
+ [0x39] = "invaliddice",
+ },
+} )
+\stopluacode
+\stopbuffer
+
+\typebuffer \getbuffer
+
+This kind of trickery is part of the font machinery used in \CONTEXT\ and permits
+runtime adaption of fonts, so we just use the same mechanism. The \type {nocheck}
+is needed to avoid this feature not kicking in due to lack of (at the time of
+checking) yet undefined dice.
+
+\startbuffer
+\definefontfeature
+ [dice:normal]
+ [default]
+ [metapost={category=dice}]
+\definefontfeature
+ [dice:reverse]
+ [default]
+ [metapost={category=dice,option=reverse}]
+\definefontfeature
+ [dice:digits]
+ [dice:digits=yes]
+
+\definefont[DiceN] [Serif*dice:normal]
+\definefont[DiceD] [Serif*dice:normal,dice:digits]
+\definefont[DiceR] [Serif*dice:reverse,dice:digits]
+
+{\DiceD Does 1 it 4 work? And {\darkgreen 3} too?} {\DiceR And how about
+{\darkred 3} then? But 8 should sort of fail!}
+\stopbuffer
+
+\typebuffer \getbuffer
+
+The six digits and \UNICODE\ characters come out the same:
+
+\startbuffer
+\red \DiceD \dostepwiserecurse {`1} {`6}{1}{\char#1\quad}%
+\blue \DiceN \dostepwiserecurse{"2680}{"2685}{1}{\char#1\quad}%
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection
+ \scale[width=\textwidth]{\getbuffer\unskip}
+\stoplinecorrection
+
+It is tempting to implement for instance~7 as two dice (a one to multi mapping in
+\OPENTYPE\ speak) but then one has to decide what combination is taken. One can
+also implement ligatures so that for instance 12 results in two six dice. But I
+think that's over the top and only showing \TEX\ muscles. It is anyway not that
+hard to do as we have an interface for that already.
+
+So why not do the dominos as well? Because there are so many dominos we predefine
+the shapes and then register the lot in a loop. We have horizontal and vertical
+variants. Being lazy I just made two helpers while one could have done but with
+some rotation and shifting of the horizontal one. The loop could be a macro but
+we don't save much code that way.
+
+\startbuffer
+\startMPcalculation{simplefun}
+
+picture Dominos[] ;
+
+Dominos[0] := image() ;
+Dominos[1] := image(draw(4,4);) ;
+Dominos[2] := image(draw(2,6);draw(6,2););
+Dominos[3] := image(draw(2,6);draw(4,4);draw(6,2););
+Dominos[4] := image(draw(2,6);draw(6,6);draw(2,2);draw(6,2););
+Dominos[5] := image(draw(2,6);draw(6,6);draw(4,4);draw(2,2);draw(6,2););
+Dominos[6] := image(draw(2,6);draw(4,6);draw(6,6);draw(2,2);draw(4,2);draw(6,2););
+
+lmt_registerglyphs [
+ name = "dominos",
+ units = 12,
+ width = 16,
+ height = 8,
+ depth = 0,
+ usecolor = true,
+] ;
+
+def DrawDominoH(expr a, b) =
+ draw image (
+ pickup pencircle scaled 1/2 ;
+ if (getparameterdefault "mpsfont" "color" "") = "black" :
+ fillup unitsquare xyscaled (16,8) ;
+ draw (8,.5) -- (8,7.5) withcolor white ;
+ pickup pencircle scaled 3/2 ;
+ draw Dominos[a]
+ withpen currentpen
+ withcolor white ;
+ draw Dominos[b] shifted (8,0)
+ withpen currentpen
+ withcolor white ;
+ else :
+ draw unitsquare xyscaled (16,8) ;
+ draw (8,0) -- (8,8) ;
+ pickup pencircle scaled 3/2 ;
+ draw Dominos[a]
+ withpen currentpen ;
+ draw Dominos[b] shifted (8,0)
+ withpen currentpen ;
+ fi ;
+ ) ;
+enddef ;
+
+def DrawDominoV(expr a, b) = % is H rotated and shifted
+ draw image (
+ pickup pencircle scaled 1/2 ;
+ if (getparameterdefault "mpsfont" "color" "") = "black" :
+ fillup unitsquare xyscaled (8,16) ;
+ draw (.5,8) -- (7.5,8) withcolor white ;
+ pickup pencircle scaled 3/2 ;
+ draw Dominos[a] rotatedaround(center Dominos[a],90)
+ withpen currentpen
+ withcolor white ;
+ draw Dominos[b] rotatedaround(center Dominos[b],90) shifted (0,8)
+ withpen currentpen
+ withcolor white ;
+ else :
+ draw unitsquare xyscaled (8,16) ;
+ draw (0,8) -- (8,8) ;
+ pickup pencircle scaled 3/2 ;
+ draw Dominos[a] rotatedaround(center Dominos[a],90)
+ withpen currentpen ;
+ draw Dominos[b] rotatedaround(center Dominos[b],90) shifted (0,8)
+ withpen currentpen ;
+ fi ;
+ ) ;
+enddef ;
+
+begingroup
+ save unicode ; numeric unicode ; unicode := 127025 ; % 1F031
+
+ for i=0 upto 6 :
+ for j=0 upto 6 :
+ lmt_registerglyph [
+ category = "dominos",
+ unicode = unicode,
+ code = "DrawDominoH(" & decimal i & "," & decimal j & ");",
+ width = 16,
+ height = 8,
+ ] ;
+ unicode := unicode + 1 ;
+ endfor ;
+ endfor ;
+
+ save unicode ; numeric unicode ; unicode := 127075 ;
+
+ for i=0 upto 6 :
+ for j=0 upto 6 :
+ lmt_registerglyph [
+ category = "dominos",
+ unicode = unicode,
+ code = "DrawDominoV(" & decimal i & "," & decimal j & ");",
+ width = 8,
+ height = 16,
+ ] ;
+ unicode := unicode + 1 ;
+ endfor ;
+ endfor ;
+endgroup ;
+
+\stopMPcalculation
+\stopbuffer
+
+\typebuffer \getbuffer
+
+Again we predefine a couple of features:
+
+\startbuffer
+\definefontfeature
+ [dominos:white]
+ [default]
+ [metapost={category=dominos}]
+
+\definefontfeature
+ [dominos:black]
+ [default]
+ [metapost={category=dominos,color=black}]
+
+\definefontfeature
+ [dominos:digits]
+ [dominos:digits=yes]
+\stopbuffer
+
+\typebuffer \getbuffer
+
+This last feature is yet to be defined. We could deal with the invalid dominos
+with some substitution trickery but let's keep it simple.
+
+\startbuffer
+\startluacode
+local ligatures = { }
+local unicode = 127025
+
+for i=0x30,0x36 do
+ for j=0x30,0x36 do
+ ligatures[unicode] = { i, j }
+ unicode = unicode + 1 ;
+ end
+end
+
+fonts.handlers.otf.addfeature("dominos:digits", {
+ type = "ligature",
+ order = { "dominos:digits" },
+ nocheck = true,
+ data = ligatures,
+} )
+\stopluacode
+\stopbuffer
+
+\typebuffer \getbuffer
+
+That leaves showing an example. We define a few fonts and again we just extend
+the Serif:
+
+\startbuffer
+\definefont[DominoW][Serif*dominos:white]
+\definefont[DominoB][Serif*dominos:black]
+\definefont[DominoD][Serif*dominos:white,dominos:digits]
+\stopbuffer
+
+\typebuffer \getbuffer
+
+The example is:
+
+\startbuffer
+\DominoW
+ \char"1F043\quad 🀱\quad
+ \char"1F052\quad 🀲\quad
+ \char"1F038\quad 🀳\quad
+ \darkgreen\char"1F049\quad \char"1F07B\quad
+\DominoB
+ \char"1F087\quad
+ \char"1F088\quad
+ \char"1F089\quad
+\DominoD
+ \darkred 12\quad56\quad64
+\stopbuffer
+
+\typebuffer
+
+Watch the ligatures in action:
+
+\startlinecorrection
+ \scale[width=\textwidth]{\getbuffer\unskip}
+\stoplinecorrection
+
+To what extent the usage of symbols like dice and dominos as characters in the
+mentioned book are responsible for them being in \UNICODE, I don't know. Now with
+all these emoji showing up one can wonder about graphics in such a standard
+anyway. But for sure, even after more than three decades, Don still makes nice
+fonts.
+
+A treasure of tiny graphics can be found in \quotation {pre-fascicle 5c} and many
+are in color! In fact, it has dominos too. It must have been a lot of fun writing
+this! I'm thinking of turning the pentominoes into a font where a \type {GPOS}
+feature can deal with the inter|-|pentomino kerning (which mighty work out okay
+for example~36. The windmill dominos also make a nice example for a font where
+ligatures will boil down to the base form and the (one or more) blades are laid
+over. It's definitely an inspiring read.
+
+\stopchapter
+
+\stoptext