meta-imp-threesix.mkxl /size: 9 Kb    last modification: 2023-12-21 09:44
1%D \module
2%D   [       file=meta-imp-threesix,
3%D        version=2019.00.00,
4%D          title=\METAPOST\ Graphics,
5%D       subtitle=Don Knuths ThreeSix font,
6%D         author=Hans Hagen,
7%D           date=\currentdate,
8%D      copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
9%C
10%C This module is part of the \CONTEXT\ macro||package and is
11%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
12%C details.
13
14%D The design of the font is if course by Don Knuth and can be found in facs9b.ps. I
15%D wish I was clever enough to understand all the good stuff in there.
16
17\startluacode
18    local unpack = unpack
19    local concat = table.concat
20    local gsub, gmatch, utfbyte = string.gsub, string.gmatch, utf.byte
21
22    local font36 = {
23        ["0"] = [[00111100 01111110 11000011 11000011 11000011 11000011 01111110 00111100]],
24        ["1"] = [[00011100 11111100 11101100 00001100 00001100 00001100 11111111 11111111]],
25        ["2"] = [[00111110 01110011 01110011 00000011 00001110 00111000 11110001 11111111]],
26        ["3"] = [[01111110 01100110 00000110 00111100 00000110 11100111 11100111 01111110]],
27        ["4"] = [[00001110 00011110 00110110 01100110 11111111 11111111 00000110 00001110]],
28        ["5"] = [[01111110 01111110 01000000 01111100 01000111 00000011 11000111 11111110]],
29        ["6"] = [[01111110 01100110 11000000 11011100 11100110 11000011 01100011 01111110]],
30        ["7"] = [[11111111 11111111 10000111 10001110 00011100 00011100 00011100 00011100]],
31        ["8"] = [[01111110 01100110 01100110 00111100 11000011 11000011 11000011 01111110]],
32        ["9"] = [[01111110 11000110 11000011 01100111 00111011 00000011 01100110 01111110]],
33        ["A"] = [[000110000 000111000 001111100 001101100 011001110 011111110 010000110 111100111]],
34        ["B"] = [[1111100 1110110 0110110 0111100 0110011 0110011 1110011 1111100]],
35        ["C"] = [[01111101 11110011 11100001 11100001 11100000 11100000 11100001 01111110]],
36        ["D"] = [[11111100 11100010 01100011 01100011 01100011 01100011 11100010 11111100]],
37        ["E"] = [[1111111 1110001 0110101 0111100 0110100 0110001 1110001 1111111]],
38        ["F"] = [[11111111 11100001 01100101 01111100 01100100 01100000 11111000 11111000]],
39        ["G"] = [[01111010 11100110 11100010 11100000 11100111 11100010 11100010 01111100]],
40        ["H"] = [[11100111 11100111 01000010 01111110 01000010 01000010 11100111 11100111]],
41        ["I"] = [[1111111 1111111 0011000 0011000 0011000 0011000 1111111 1111111]],
42        ["J"] = [[01111111 01111111 00000110 00000110 11110110 01100110 01100110 00111100]],
43        ["K"] = [[11101110 11100100 01101000 01110000 01111000 01101100 11100110 11101111]],
44        ["L"] = [[111111000 111111000 011000000 011000000 011000000 011000011 111000011 111111111]],
45        ["M"] = [[1100000011 1110000111 0111111110 0100110010 0100110010 0100000010 1100000011 1100000011]],
46        ["N"] = [[11000011 11100011 01110010 01111010 01011110 01001110 11100110 11100010]],
47        ["O"] = [[01111110 11000011 11000011 11000011 11000011 11000011 11000011 01111110]],
48        ["P"] = [[11111110 11100011 01100011 01111110 01100000 01100000 11111000 11111000]],
49        ["Q"] = [[01111100 11000110 11000110 11000110 11000110 11001110 11000110 01111101]],
50        ["R"] = [[11111100 11100110 01100110 01111100 01101000 01100100 11100010 11100111]],
51        ["S"] = [[01111110 11100001 11100001 01111000 00011110 10000111 11000011 10111110]],
52        ["T"] = [[1111111111 1100110011 1100110011 0000110000 0000110000 0000110000 0001111000 0001111000]],
53        ["U"] = [[111101111 111101111 011000010 011000010 011000010 011000010 011000010 001111100]],
54        ["V"] = [[11111000111 11111000111 01110000010 00110000100 00111000100 00011001000 00001101000 00001110000]],
55        ["W"] = [[111000000111 111000000111 110000000010 011000000100 011001000100 001101101000 001101101000 0001101100000]],
56        ["X"] = [[1111001110 1111000110 0001101000 0000110000 0000110000 0001011000 0110001111 0111001111]],
57        ["Y"] = [[111100011 111100011 011000010 001110100 000111000 000011000 001111110 001111110]],
58        ["Z"] = [[11111111 10000111 00001110 00011100 00111000 01110000 11100001 11111111]],
59
60        -- these don't have the 36 dots property:
61
62        [","] = [[0000 0000 0000 0000 0000 0011 0111 0111]],
63        [";"] = [[0011 0011 0011 0000 0000 0011 0111 0111]],
64        ["."] = [[0000 0000 0000 0000 0000 0111 0111 0111]],
65        [":"] = [[0111 0111 0111 0000 0000 0111 0111 0111]],
66        ["!"] = [[0111 0111 0111 0111 0111 0000 0111 0111]],
67        ["?"] = [[11111 10111 00111 01110 01110 00000 01110 01110]],
68
69        [utf.char(0x00AD)] = [[00000 00000 00000 11111 11111 00000 00000 00000]], -- hyphen
70        [utf.char(0x2013)] = [[0000000 0000000 0000000 1111111 1111111 0000000 0000000 0000000]], -- endash
71        [utf.char(0x2014)] = [[000000000 000000000 000000000 111111111 111111111 000000000 000000000 000000000]], -- emdash
72    }
73
74    MP.font36 = font36
75
76    local f_code  = string.formatters["ThreeSix(%s);"]
77    local replace = { ["0"] = "N;", ["1"] = "Y;", [" "] = "L;" }
78
79    local function remap(str)
80        -- permit abundant spacing (bonus)
81        str = gsub(str,"%s+", " ")
82        -- remap what we got to macro calls
83        str = gsub(str,".",replace)
84        -- return the result
85        return str
86    end
87
88    function MP.registerthreesix(name)
89        fonts.dropins.registerglyphs {
90            name     = name,
91            units    = 12,
92            usecolor = true,
93            preamble = "InitializeThreeSix;",
94        }
95        for u, v in table.sortedhash(font36) do
96            local data   = remap(v)
97            local ny     = 8
98            local nx     = ((#v + 1) // ny) - 1
99            local height = ny * 1.1 - 0.1
100            local width  = nx * 1.1 - 0.1
101            fonts.dropins.registerglyph {
102                category = name,
103                unicode  = utfbyte(u),
104                width    = width,
105                height   = height,
106                code     = f_code(data),
107            }
108        end
109    end
110    MP.registerthreesix("fontthreesix")
111\stopluacode
112
113\startMPcalculation{simplefun}
114    def InitializeThreeSix =
115        save Y, N, L, S ;
116        save shape, fillcolor, mypen, random, threesixpen, spread, hoffset ;
117        string shape, fillcolor, mypen ; boolean random ; pen threesixpen ;
118        shape       := getparameterdefault "mpsfont" "shape"  "circle" ;
119        random      := hasoption           "mpsfont" "random" "true" ;
120        fillcolor   := getparameterdefault "mpsfont" "color"  "" ;
121        mypen       := getparameterdefault "mpsfont" "pen"    "" ;
122        spread      := getparameterdefault "mpsfont" "spread" 0 ;
123        hoffset     := 12 * spread / 2 ;
124        threesixpen := pencircle
125            if mypen = "fancy" :
126                xscaled 1/20 yscaled 2/20 rotated 45
127            else :
128                scaled 1/20
129            fi ;
130        if shape == "square" :
131            def S =
132                unitsquare if random : randomized 1/10 fi
133                shifted (nx,ny)
134            enddef ;
135        elseif shape = "diamond" :
136            def S =
137                unitdiamond if random : randomized 1/10 fi
138                shifted (nx,ny)
139            enddef ;
140        else :
141            def S =
142                unitcircle if random : randomizedcontrols 1/20 fi
143                shifted (nx,ny)
144            enddef ;
145        fi ;
146        if fillcolor = "" :
147            def N =
148                nx := nx + dx ;
149                draw S ;
150            enddef ;
151        else :
152            def N =
153                nx := nx + dx ;
154                draw S withcolor "lightgray" ;
155            enddef ;
156        fi ;
157        if fillcolor = "random" :
158            def Y =
159                nx := nx + dx ;
160                fillup S withcolor white randomized (2/3,2/3,2/3) ;
161            enddef ;
162        elseif fillcolor = "" :
163            def Y =
164                nx := nx + dx ;
165                fillup S ;
166            enddef ;
167        else :
168            def Y =
169                nx := nx + dx ;
170                fillup S withcolor fillcolor ;
171            enddef ;
172        fi ;
173        def L =
174            nx := - dx ;
175            ny := ny + dy ;
176        enddef ;
177    enddef ;
178
179    vardef ThreeSix (text code) =
180        save dx, dy, nx, ny ;
181        dx :=   11/10 ;
182        dy := - 11/10 ;
183        nx := - dx ;
184        ny :=   0 ;
185        pickup threesixpen ;
186        draw image (code) shifted (hoffset,-ny) ;
187    enddef ;
188\stopMPcalculation
189
190% spacing=.25 plus .1 minus .05 extra .25
191
192\definefontfeature % black and white, with some spread
193  [fontthreesix]
194  [default]
195  [metapost=fontthreesix]
196
197\definefontfeature % color, with some spread
198  [fontthreesix-tweak]
199  [default]
200  [metapost={category=fontthreesix,spread=.1}]
201
202\definefontfeature % color, with some spread
203  [fontthreesix-color]
204  [default]
205  [metapost={category=fontthreesix,shape=diamond,color=random,pen=fancy,spread=.1}]
206
207\definefontfeature % color, tight
208  [fontthreesix-initial]
209  [metapost={category=fontthreesix,color=random,shape=circle}] % units?
210
211\definefont[DEKFontA][Serif*fontthreesix]
212\definefont[DEKFontB][Serif*fontthreesix-color]
213\definefont[DEKFontC][Serif*fontthreesix-initial]
214\definefont[DEKFontD][Serif*fontthreesix-tweak]
215
216\continueifinputfile{meta-imp-threesix.mkxl}
217
218\starttext
219
220\definefontfeature % color, with some spread
221  [fontthreesix-color]
222  [default]
223  [metapost={category=fontthreesix,shape=diamond,color=random,pen=fancy,spread=.1,random=yes}]
224
225\definefont[DEKFontA][Serif*fontthreesix-color @ 200pt]
226\definefont[DEKFontB][Serif*fontthreesix-color @  12pt]
227
228% Or course:
229
230\startTEXpage[offset=1dk]
231    \DEKFontA TEX
232\stopTEXpage
233
234\startTEXpage[offset=1dk]
235    \DEKFontA T\kern-0.05em\lower.75\exheight\hbox{E}\kern-.05emX
236\stopTEXpage
237
238% We only have uppercase characters! But I added a few punctuation symbols so that
239% we can do the following. Actually we can consider lowercase to be just smaller and
240% another shape.
241
242\startTEXpage[offset=1dk,align=flushleft,foregroundstyle=\DEKFontB]
243    \WORD{\input{knuth}}
244\stopTEXpage
245
246\stoptext
247