1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20\ifcase\contextlmtxmode\else
21 \writestatus{punk}{use metapost library punk instead}
22 \expandafter\endinput
23\fi
24
25\startluacode
26local concat = table.concat
27local round = math.round
28local chardata = characters.data
29local fontdata = fonts.hashes.identifiers
30
31fonts.mp = fonts.mp or { }
32
33fonts.mp.version = fonts.mp.version or 1.15
34fonts.mp.inline = true
35fonts.mp.cache = containers.define("fonts", "mp", fonts.mp.version, true)
36
37metapost.characters = metapost.characters or { }
38
39
40
41local characters, descriptions = { }, { }
42local factor, l, n, w, h, d, total, variants = 100, { }, 0, 0, 0, 0, 0, 0, true
43
44
45
46
47local flusher = {
48 startfigure = function(chrnum,llx,lly,urx,ury)
49 l, n = { }, chrnum
50 w, h, d = urx - llx, ury, -lly
51 total = total + 1
52 inline = fonts.mp.inline
53 end,
54 flushfigure = function(t)
55 for i=1, #t do
56 l[#l+1] = t[i]
57 end
58 end,
59 stopfigure = function()
60 local cd = chardata[n]
61 if inline then
62 descriptions[n] = {
63
64 name = cd and cd.adobename,
65 width = w*100,
66 height = h*100,
67 depth = d*100,
68 boundingbox = { 0, -d, w, h },
69 }
70 characters[n] = {
71 commands = {
72 { "pdf", concat(l," ") },
73 }
74 }
75 else
76 descriptions[n] = {
77
78 name = cd and cd.adobename,
79 width = w*100,
80 height = h*100,
81 depth = d*100,
82 boundingbox = { 0, -d, w, h },
83 }
84 characters[n] = {
85 commands = {
86 { "image", { stream = concat(l," "), bbox = { 0, -d*65536, w*65536, h*65536 } } },
87 }
88 }
89 end
90 end
91}
92
93metapost.characters.instances = metapost.characters.instances or 10
94
95function metapost.characters.process(mpxformat, name, instances, scalefactor)
96 statistics.starttiming(metapost.characters)
97 scalefactor = scalefactor or 1
98 instances = instances or metapost.characters.instances or 10
99 local fontname = file.removesuffix(file.basename(name))
100 local hash = file.robustname(string.format("%s %05i %03i", fontname, round(scalefactor*1000), instances))
101 local lists = containers.read(fonts.mp.cache, hash)
102 if not lists then
103 statistics.starttiming(flusher)
104
105 local data = io.loaddata(resolvers.findfile(name))
106 metapost.reset(mpxformat)
107 metapost.setoutercolor(2)
108 lists = { }
109 for i=1,instances do
110 characters = { }
111 descriptions = { }
112 metapost.process {
113 mpx = mpxformat,
114
115 flusher = flusher,
116
117
118 askedfig = "all",
119
120 data = {
121 "randomseed := " .. i*10 .. ";",
122 "scale_factor := " .. scalefactor .. " ;",
123 data
124 },
125 }
126 lists[i] = {
127 characters = characters,
128 descriptions = descriptions,
129 parameters = {
130 designsize = 655360,
131 slant = 0,
132 space = 333 * scalefactor,
133 space_stretch = 166.5 * scalefactor,
134 space_shrink = 111 * scalefactor,
135 x_height = 431 * scalefactor,
136 quad = 1000 * scalefactor,
137 extra_space = 0,
138 },
139 properties = {
140 name = string.format("%s-%03i",hash,i),
141 virtualized = true,
142 spacer = "space",
143 }
144 }
145 end
146 metapost.reset(mpxformat)
147 lists = containers.write(fonts.mp.cache, hash, lists)
148 statistics.stoptiming(flusher)
149 end
150 variants = variants + #lists
151 statistics.stoptiming(metapost.characters)
152 return lists
153end
154
155function fonts.handlers.vf.combiner.commands.metafont(g,v)
156 local size = g.specification.size
157 local data = metapost.characters.process(v[2],v[3],v[4],size/655360)
158 local list, t = { }, { }
159 for d=1,#data do
160 t = data[d]
161 t = fonts.constructors.scale(t, -1000)
162 local id = font.nextid()
163 t.fonts = { { id = id } }
164 fontdata[id] = t
165 fonts.handlers.vf.helpers.composecharacters(t)
166 list[d] = font.define(t)
167 end
168 for k, v in next, t do
169 g[k] = v
170 end
171 g.properties.virtualized = true
172 g.variants = list
173end
174
175fonts.definers.methods.install( "punk", {
176 { "metafont", "mfplain", "punkfont.mp", 10 },
177} )
178fonts.definers.methods.install( "punkbold", {
179 { "metafont", "mfplain", "punkfont-bold.mp", 10 },
180} )
181fonts.definers.methods.install( "punkslanted", {
182 { "metafont", "mfplain", "punkfont-slanted.mp", 10 },
183} )
184fonts.definers.methods.install( "punkboldslanted", {
185 { "metafont", "mfplain", "punkfont-boldslanted.mp", 10 },
186} )
187
188
189
190
191
192
193
194
195
196
197
198
199local getfont = nodes.nuts.getfont
200local setfield = nodes.nuts.setfield
201local random = math.random
202
203typesetters.cases.register("RandomPunk", function(start)
204 local used = fontdata[getfont(start)].variants
205 if used then
206 local f = random(1,#used)
207 setfield(start,"font",used[f])
208 return start, true
209 else
210 return start, false
211 end
212end)
213
214metapost.characters.flusher = flusher
215
216statistics.register("metapost font generation", function()
217 local time = statistics.elapsedtime(flusher)
218 if total > 0 then
219 return string.format("%i glyphs, %s seconds runtime, %0.3f glyphs/second", total, time, total/tonumber(time))
220 else
221 return string.format("%i glyphs, %s seconds runtime", total, time)
222 end
223end)
224
225statistics.register("metapost font loading",function()
226 local time = statistics.elapsedtime(metapost.characters)
227 if variants > 0 then
228 return string.format("%s seconds, %i instances, %0.3f instances/second", time, variants, variants/tonumber(time))
229 else
230 return string.format("%s seconds, %i instances", time, variants)
231 end
232end)
233\stopluacode
234
235\unexpanded\def\EnableRandomPunk {\setcharactercasing[RandomPunk]}
236\unexpanded\def\RandomPunk {\groupedcommand\EnableRandomPunk\donothing}
237\unexpanded\def\StartRandomPunk {\begingroup\EnableRandomPunk}
238\unexpanded\def\StopRandomPunk {\endgroup}
239
240\starttypescript [serif] [punk]
241 \definefontsynonym [Serif] [demo@punk]
242 \definefontsynonym [SerifBold] [demobold@punkbold]
243 \definefontsynonym [SerifSlanted] [demoslanted@punkslanted]
244 \definefontsynonym [SerifBoldSlanted] [demoboldslanted@punkboldslanted]
245 \definefontsynonym [SerifItalic] [SerifSlanted]
246 \definefontsynonym [SerifBoldItalic] [SerifBoldSlanted]
247\stoptypescript
248
249\starttypescript [punk]
250 \definetypeface [punk] [rm] [serif] [punk] [default]
251\stoptypescript
252
253\continueifinputfile{mpunk.mkiv}
254
255\usetypescript[punk]
256
257\setupbodyfont[punk,14pt]
258
259\starttext
260 \definedfont[demo@punk at 10pt]hello world\par
261 \definedfont[demo@punk at 12pt]hello world\par
262 \definedfont[demo@punk at 16pt]hello world\par
263 \definedfont[demo@punk at 20pt]hello world\par
264\stoptext
265
266 |