m-fonts-plugins.mkiv /size: 13 Kb    last modification: 2021-10-28 13:50
1%D \module
2%D   [      file=m-fonts-plugins,
3%D        version=2016.10.10,
4%D          title=\CONTEXT\ Fonts,
5%D       subtitle=Font Engine Plugins,
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 See source code for comments. I wrote this a follow up on a presentation by Kai
15%D Eigner at an NTG meeting, then left it for a while, and sort of finalized it the
16%D last quarter of 2016. As I don't use this module, apart from maybe testing
17%D something, it is not guaranteed to work (but fixing should be a no real problem
18%D as I expect apis to be stable). Plugins like this can interfere with other
19%D functionality in \CONTEXT\ so don't expect too much support. The two modules
20%D mentioned below should work in the generic loader too. It's anyhow an
21%D illustration of how \type {ffi} be used in a practical application.
22%D
23%D I'm not sure if Idris will ever need this but the code has been used for some
24%D articles so that's why it's eventually shipped.
25%D
26%D The library is supposed to be present in
27%D
28%D \starttyping
29%D .../tex/texmf-win64/bin/lib/luatatex/harfbuzz/libharfbuzz-0.dll
30%D .../tex/texmf-win64/bin/lib/luametatex/harfbuzz/libharfbuzz-0.dll
31%D
32%D .../tex/texmf-*/bin/lib/luatatex/harfbuzz/libharfbuzz.so
33%D .../tex/texmf-*/bin/lib/luametatex/harfbuzz/libharfbuzz.so
34%D \stoptyping
35%D
36%D It might be found on the system if paths are set but with libraries that render
37%D (font) stuff it's best to rely on what you explictly installed. When you install
38%D files there make sure to run \type {mtxrun --generate}. Keep in mind that we don't
39%D officially support such dependencies (bug-wise).
40%D
41%D In mkiv we support binary and library, and in lmtx binary and internal where we
42%D default to library or internal as binary is not that fast (more meant as a
43%D playground I guess). You can track loading with:
44%D
45%D \starttyping
46%D \enabletrackers[resolvers.ffilib]
47%D \stoptyping
48%D
49%D This file has always been in the distribution but per end april 2021 the font-txt,
50%D font-phb and font-phb-imp-* files are in the distrinbution too. It's a side effect
51%D of some cleanup of the (luametatex) source tree (where the optional module was not
52%D yet in sync with the other optional ones). This module is mostly for myself and
53%D Idris if only because it is not tested for interferences with all kind of other
54%D font code (and it's unlikely to happen), so don't depend on this!
55
56% \starttext
57%
58%     \definefontfeature [native] [default]
59%       [mode=plug,
60%        features=harfbuzz,
61%        shaper=native]
62%
63%     \definefontfeature [uniscribe] [default]
64%       [mode=plug,
65%        features=harfbuzz,
66%        shaper=uniscribe]
67%
68%     \definefontfeature [binary] [default]
69%       [mode=plug,
70%        method=binary,
71%        features=harfbuzz,
72%        shaper=uniscribe]
73%
74%     % \nohyphens
75%     \definedfont[Serif*default]   fiets \par % \input tufte \par
76%     \definedfont[Serif*native]    fiets \par % \input tufte \par
77%     \definedfont[Serif*uniscribe] fiets \par % \input tufte \par
78%     \definedfont[Serif*binary]    fiets \par % \input tufte \par
79%
80% \stoptext
81
82
83\registerctxluafile{font-phb}{autosuffix}
84
85\startluacode
86
87    local function processlist(data)
88        local list    = data.list
89        local timings = data.results
90        for i=1,#list do
91            local name = list[i]
92            local data = timings[name]
93            local none = data["context none"] or 0
94            local node = data["context node"] or 0
95            if node > 0.1 then
96                context.starttabulate { "|l|c|c|c|c|c|" }
97                    context.NC() context.bold(name)
98                    context.NC() context([[$t$]])
99                    context.NC() context([[$t - t_{\hbox{\tx none}}$]])
100                    context.NC() context([[$t - t_{\hbox{\tx node}}$]])
101                    context.NC() context([[$t / t_{\hbox{\tx node}}$]])
102                    context.NC() context([[$\frac{t - t_{\hbox{\txx none}}}{t_{\hbox{\txx node}} - t_{\hbox{\txx none}}}$]])
103                    context.NC() context.NR()
104                    context.TL()
105                    for k, v in table.sortedhash(data) do
106                        context.NC() context(k)
107                        context.NC() context("%0.2f",v)
108                        context.NC() context("%0.2f",v - none)
109                        context.NC() context("%0.2f",v - node)
110                        context.NC() context("%0.2f",v / node)
111                        context.NC() if node ~= none then context("%0.2f",(v-none) / (node-none)) end
112                        context.NC() context.NR()
113                    end
114                context.stoptabulate()
115            end
116        end
117    end
118
119    moduledata.plugins = {
120        processlist = processlist,
121    }
122
123\stopluacode
124
125\continueifinputfile{m-fonts-plugins.mkiv}
126
127\usemodule[art-01]
128
129\starttext
130
131\edef\tufte{\cldloadfile{tufte.tex}}
132\edef\khatt{\cldloadfile{khatt-ar.tex}}
133
134\startbuffer[latin-definitions]
135\definefont[TestA][Serif*test]
136\definefont[TestB][SerifItalic*test]
137\definefont[TestC][SerifBold*test]
138\stopbuffer
139
140\startbuffer[latin-text]
141\TestA \tufte \par
142\TestB \tufte \par
143\TestC \tufte \par
144\dorecurse {10} {%
145    \TestA Fluffy Test Font A
146    \TestB Fluffy Test Font B
147    \TestC Fluffy Test Font C
148}\par
149\stopbuffer
150
151\startbuffer[arabic-definitions]
152\definedfont[Arabic*test at 14pt]
153\setupinterlinespace[line=18pt]
154\setupalign[r2l]
155\stopbuffer
156
157\startbuffer[arabic-text]
158\dorecurse {10} {
159    \khatt\space
160    \khatt\space
161    \khatt
162    \blank
163}
164\stopbuffer
165
166\startbuffer[mixed-definitions]
167\definefont[TestL][Serif*test]
168\definefont[TestA][Arabic*test at 14pt]
169\setupinterlinespace[line=18pt]
170\setupalign[r2l]
171\stopbuffer
172
173\startbuffer[mixed-text]
174\dorecurse {2} {
175    {\TestA\khatt\space\khatt\space\khatt}
176    {\TestL\lefttoright\tufte}
177    \blank
178    \dorecurse{10}{%
179        {\TestA وَ قَرْمِطْ بَيْنَ الْحُرُوفِ؛ فَإِنَّ}
180        {\TestL\lefttoright A snippet text that makes no sense.}
181    }
182}
183\stopbuffer
184
185\definefontfeature
186  [test-none]
187  [mode=none]
188
189\definefontfeature
190  [test-base]
191  [mode=base,
192   liga=yes,
193   kern=yes]
194
195% no tlig and no analyze
196
197\definefontfeature
198  [test-node]
199  [mode=node,
200   script=auto,
201   autoscript=position,
202   autolanguage=position,
203   ccmp=yes,
204   liga=yes,
205 % rlig=yes,
206 % hlig=yes,
207 % dlig=yes,
208   clig=yes,
209   kern=yes,
210   mark=yes,
211   mkmk=yes,
212   curs=yes]
213
214\definefontfeature
215  [test-text]
216  [mode=plug,
217   features=text]
218
219\definefontfeature
220  [test-native]
221  [mode=plug,
222   features=harfbuzz,
223  %liga=yes,
224  %kern=yes,
225   shaper=native]
226
227\definefontfeature
228  [test-uniscribe]
229  [mode=plug,
230   features=harfbuzz,
231  %liga=yes,
232  %kern=yes,
233   shaper=uniscribe]
234
235\definefontfeature
236  [test-binary]
237  [mode=plug,
238   features=harfbuzz,
239  %liga=yes,
240  %kern=yes,
241   shaper=uniscribe,
242   method=binary]
243
244\definefontfeature
245  [arabic-node]
246  [arabic]
247  [salt=yes] % seems to be needed for husayni
248
249\definefontfeature
250  [arabic-native]
251  [mode=plug,
252   features=harfbuzz,
253 % method=binary,
254% method=internal,
255   script=arab,language=dflt,
256%    ccmp=yes,
257%    init=yes,medi=yes,fina=yes,isol=yes,
258%    liga=yes,dlig=yes,rlig=yes,clig=yes,calt=yes,
259%    mark=yes,mkmk=yes,kern=yes,curs=yes,
260   shaper=native]
261
262\definefontfeature
263  [arabic-uniscribe]
264  [mode=plug,
265   features=harfbuzz,
266   script=arab,language=dflt,
267%    ccmp=yes,
268%    init=yes,medi=yes,fina=yes,isol=yes,
269%    liga=yes,dlig=yes,rlig=yes,clig=yes,calt=yes,
270%    mark=yes,mkmk=yes,kern=yes,curs=yes,
271   shaper=uniscribe]
272
273\starttexdefinition RunLatinTest #1#2#3#4#5
274    \start
275        \dontcomplain
276        \definefontfeature[test][test-#4]
277        \writestatus{warning}{#1 #3 #4 (1 initial run)}
278        \page
279        \startluacode
280            collectgarbage("collect")
281        \stopluacode
282        \title{#1 #3 #4}
283        \start
284            \getbuffer[#5-definitions]
285            \showfontkerns
286            \showmakeup[discretionary]
287          % \enabletrackers[fonts.plugins.hb.colors]%
288            \testfeatureonce{1}{
289                \getbuffer[#5-text]
290            }
291        \stop
292        \page
293        \startluacode
294            collectgarbage("collect")
295        \stopluacode
296        \ifnum#2>1\relax
297            \writestatus{warning}{#1 #3 #4 (#2 timing runs)}
298            \start
299                \getbuffer[#5-definitions]
300                \testfeatureonce{#2}{
301                    \setbox\scratchbox\hbox{\getbuffer[#5-text]}
302                }
303            \stop
304            \writestatus{warning}{done}
305        \fi
306        \startluacode
307            document.collected_timings.timings["#5"].results["#1"]["#3 #4"] = \elapsedtime\space
308            collectgarbage("collect")
309        \stopluacode
310    \stop
311\stoptexdefinition
312
313\starttexdefinition RunArabicTest #1#2#3#4#5
314    \start
315        \dontcomplain
316        \definefontsynonym[Arabic][#1]
317        \definefontfeature[test][arabic-#4]
318        \writestatus{warning}{#1 #3 #4 #5 (1 initial run)}
319        \page
320        \startluacode
321            collectgarbage("collect")
322        \stopluacode
323        \title{#1 #3 #4}
324        \start
325            \getbuffer[#5-definitions]
326          % \enabletrackers[fonts.plugins.hb.colors]%
327            \testfeatureonce{1}{
328                \setupalign[flushleft] % easier to compare
329                \getbuffer[#5-text]
330            }
331            \par
332        \stop
333        \page
334        \ifnum#2>1\relax
335            \writestatus{warning}{#1 #3 #4 #5 (#2 timing runs)}
336            \start
337                \getbuffer[#5-definitions]
338                \testfeatureonce{#2}{
339                    \setbox\scratchbox\hbox{\getbuffer[#5-text]}
340                }
341            \stop
342            \writestatus{warning}{done}
343        \fi
344        \startluacode
345            document.collected_timings.timings["#5"].results["#1"]["#3 #4"] = \elapsedtime\space
346            collectgarbage("collect")
347        \stopluacode
348    \stop
349\stoptexdefinition
350
351\startluacode
352    local processlist = moduledata.plugins.processlist
353
354    local data = {
355        timings = { },
356        engine  = jit and "luajittex" or "luatex",
357    }
358
359    document.collected_timings = data
360
361    -- LATIN
362
363    local list = {
364       "modern",
365       "pagella",
366       "dejavu",
367       "cambria",
368       "ebgaramond",
369       "lucidaot"
370    }
371
372    data.timings["latin"] = {
373        list    = list,
374        results = table.setmetatableindex("table"),
375    }
376
377    for i=1,#list do
378
379        local name = list[i]
380
381        context.setupbodyfont { name }
382        context.RunLatinTest (name, 100, "context",  "none",      "latin")
383        context.RunLatinTest (name, 100, "context",  "base",      "latin")
384        context.RunLatinTest (name, 100, "context",  "node",      "latin")
385        context.RunLatinTest (name, 100, "harfbuzz", "native",    "latin")
386        context.RunLatinTest (name, 100, "harfbuzz", "uniscribe", "latin")
387     -- context.RunLatinTest (name,   1, "context",  "text",      "latin")
388     -- context.RunLatinTest (name,   1, "harfbuzz", "binary",    "latin")
389
390    end
391
392    context(function()
393        context.page()
394        context.title((jit and "luajittex" or "luatex") .. " latin")
395        processlist(data.timings["latin"])
396        context.page()
397    end)
398
399    -- ARABIC
400
401    local list = {
402        "arabtype",
403        "husayni",
404    }
405
406    data.timings["arabic"] = {
407        list    = list,
408        results = table.setmetatableindex("table")
409    }
410
411    for i=1,#list do
412
413        local name = list[i]
414
415        context.setupbodyfont { name }
416        context.RunArabicTest (name, 100, "context",  "none",      "arabic")
417        context.RunArabicTest (name, 100, "context",  "base",      "arabic")
418        context.RunArabicTest (name, 100, "context",  "node",      "arabic")
419        context.RunArabicTest (name, 100, "harfbuzz", "native",    "arabic")
420        context.RunArabicTest (name, 100, "harfbuzz", "uniscribe", "arabic")
421     -- context.RunArabicTest (name,   1, "context",  "text",      "arabic")
422     -- context.RunArabicTest (name,   1, "harfbuzz", "binary",    "arabic")
423
424    end
425
426    context(function()
427        context.page()
428        context.title((jit and "luajittex" or "luatex") .. " arabic")
429        processlist(data.timings["arabic"])
430        context.page()
431    end)
432
433    -- MIXED
434
435    local list = {
436        "arabtype",
437        "husayni"
438    }
439
440    data.timings["mixed"] = {
441        list    = list,
442        results = table.setmetatableindex("table")
443    }
444
445    for i=1,#list do
446
447        local name = list[i]
448
449        context.setupbodyfont { name }
450        context.RunArabicTest (name, 100, "context",  "none",      "mixed")
451        context.RunArabicTest (name, 100, "context",  "base",      "mixed")
452        context.RunArabicTest (name, 100, "context",  "node",      "mixed")
453        context.RunArabicTest (name, 100, "harfbuzz", "native",    "mixed")
454        context.RunArabicTest (name, 100, "harfbuzz", "uniscribe", "mixed")
455     -- context.RunArabicTest (name,   1, "context",  "text",      "mixed")
456     -- context.RunArabicTest (name,   1, "harfbuzz", "binary",    "mixed")
457
458    end
459
460    context(function()
461        context.page()
462        context.title((jit and "luajittex" or "luatex") .. " mixed")
463        processlist(data.timings["mixed"])
464        context.page()
465    end)
466
467    context(function()
468        table.save("m-fonts-plugins-timings-" .. (jit and "luajittex" or "luatex") .. ".lua",data)
469    end)
470
471\stopluacode
472
473\stoptext
474