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
34
35
36
37local P, Ct, Cc = lpeg.P, lpeg.Ct, lpeg.Cc
38local lpegmatch = lpeg.match
39
40local zero = Cc(0)
41local number = lpeg.patterns.integer / tonumber + zero
42local index = lpeg.patterns.cardinal / tonumber
43local cluster = index
44local offset = (P("@") * number * (P(",") * number + zero)) + zero * zero
45local advance = (P("+") * number * (P(",") * number + zero)) + zero * zero
46local glyph = Ct(index * P("=") * cluster * offset * advance)
47local pattern = Ct(P("[") * (glyph * P("|")^-1)^0 * P("]"))
48
49local shapers = {
50 native = "ot,uniscribe,fallback",
51 uniscribe = "uniscribe,ot,fallback",
52 fallback = "fallback"
53}
54
55local runner = sandbox.registerrunner {
56 method = "resultof",
57 name = "harfbuzz",
58
59
60
61
62 program = "hb-shape",
63 checkers = {
64 shaper = "string",
65 features = "string",
66 script = "string",
67 language = "string",
68 direction = "string",
69 textfile = "writable",
70 fontfile = "readable",
71 },
72 template = string.longtostring [[
73 --shaper=%shaper%
74 --output-format=text
75 --no-glyph-names
76 --features="%features%"
77 --script=%script%
78 --language=%language%
79 --direction=%direction%
80 --text-file=%textfile%
81 --font-file=%fontfile%
82 ]],
83}
84
85local tempfile = "font-phb.tmp"
86local reported = false
87
88function utilities.hb.methods.binary(font,data,rlmode,text,leading,trailing)
89 if runner then
90 savedata(tempfile,packtoutf8(text,leading,trailing))
91 local result = runner {
92 shaper = shapers[data.shaper] or shapers.native,
93 features = data.features,
94 script = data.script or "dflt",
95 language = data.language or "dflt",
96 direction = rlmode < 0 and "rtl" or "ltr",
97 textfile = tempfile,
98 fontfile = data.filename,
99 }
100 removefile(tempfile)
101 if result then
102
103 result = lpegmatch(pattern,result)
104 if rlmode < 0 then
105 return reverse(result)
106 else
107 return result
108 end
109 end
110 elseif reported then
111 report("no runner available")
112 reported = true
113 end
114end
115 |