1if not modules then modules = { } end modules ['font-phb-imp-binary'] = {
2 version = 1.000,
3 comment = "companion to font-txt.mkiv",
4 author = "Hans Hagen",
5 copyright = "PRAGMA ADE / ConTeXt Development Team",
6 license = "see context related readme files",
7}
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22local next, tonumber, pcall = next, tonumber, pcall
23
24local concat = table.concat
25local reverse = table.reverse
26local formatters = string.formatters
27local removefile = os.remove
28local resultof = os.resultof
29local savedata = io.savedata
30
31local report = utilities.hb.report or print
32local packtoutf8 = utilities.hb.helpers.packtoutf8
33
34if not context then
35 report("the binary runner is only supported in context")
36 return
37end
38
39
40
41
42local P, Ct, Cc = lpeg.P, lpeg.Ct, lpeg.Cc
43local lpegmatch = lpeg.match
44
45local zero = Cc(0)
46local number = lpeg.patterns.integer / tonumber + zero
47local index = lpeg.patterns.cardinal / tonumber
48local cluster = index
49local offset = (P("@") * number * (P(",") * number + zero)) + zero * zero
50local advance = (P("+") * number * (P(",") * number + zero)) + zero * zero
51local glyph = Ct(index * P("=") * cluster * offset * advance)
52local pattern = Ct(P("[") * (glyph * P("|")^-1)^0 * P("]"))
53
54local shapers = {
55 native = "ot,uniscribe,fallback",
56 uniscribe = "uniscribe,ot,fallback",
57 fallback = "fallback"
58}
59
60local runner = sandbox.registerrunner {
61 method = "resultof",
62 name = "harfbuzz",
63
64
65
66
67 program = "hb-shape",
68 checkers = {
69 shaper = "string",
70 features = "string",
71 script = "string",
72 language = "string",
73 direction = "string",
74 textfile = "writable",
75 fontfile = "readable",
76 },
77 template = string.longtostring [[
78 --shaper=%shaper%
79 --output-format=text
80 --no-glyph-names
81 --features="%features%"
82 --script=%script%
83 --language=%language%
84 --direction=%direction%
85 --text-file=%textfile%
86 --font-file=%fontfile%
87 ]],
88}
89
90local tempfile = "font-phb.tmp"
91local reported = false
92
93function utilities.hb.methods.binary(font,data,rlmode,text,leading,trailing)
94 if runner then
95 savedata(tempfile,packtoutf8(text,leading,trailing))
96 local result = runner {
97 shaper = shapers[data.shaper] or shapers.native,
98 features = data.features,
99 script = data.script or "dflt",
100 language = data.language or "dflt",
101 direction = rlmode < 0 and "rtl" or "ltr",
102 textfile = tempfile,
103 fontfile = data.filename,
104 }
105 removefile(tempfile)
106 if result then
107
108 result = lpegmatch(pattern,result)
109 if rlmode < 0 then
110 return reverse(result)
111 else
112 return result
113 end
114 end
115 elseif reported then
116 report("no runner available")
117 reported = true
118 end
119end
120 |