1if not modules then modules = { } end modules ['luatex-fonts-ext'] = {
2 version = 1.001,
3 comment = "companion to luatex-*.tex",
4 author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
5 copyright = "PRAGMA ADE / ConTeXt Development Team",
6 license = "see context related readme files"
7}
8
9if context then
10 os.exit()
11end
12
13local byte = string.byte
14
15local fonts = fonts
16local handlers = fonts.handlers
17local otf = handlers.otf
18local afm = handlers.afm
19local registerotffeature = otf.features.register
20local registerafmfeature = afm.features.register
21
22
23
24function fonts.loggers.onetimemessage() end
25
26
27
28
29
30
31
32
33
34fonts.protrusions = fonts.protrusions or { }
35fonts.protrusions.setups = fonts.protrusions.setups or { }
36local setups = fonts.protrusions.setups
37
38setups['default'] = {
39
40 factor = 1,
41 left = 1,
42 right = 1,
43
44 [0x002C] = { 0, 1 },
45 [0x002E] = { 0, 1 },
46 [0x003A] = { 0, 1 },
47 [0x003B] = { 0, 1 },
48 [0x002D] = { 0, 1 },
49 [0x2013] = { 0, 0.50 },
50 [0x2014] = { 0, 0.33 },
51 [0x3001] = { 0, 1 },
52 [0x3002] = { 0, 1 },
53 [0x060C] = { 0, 1 },
54 [0x061B] = { 0, 1 },
55 [0x06D4] = { 0, 1 },
56
57}
58
59local function initializeprotrusion(tfmdata,value)
60 if value then
61 local setup = setups[value]
62 if setup then
63 local factor, left, right = setup.factor or 1, setup.left or 1, setup.right or 1
64 local emwidth = tfmdata.parameters.quad
65 tfmdata.parameters.protrusion = {
66 auto = true,
67 }
68 for i, chr in next, tfmdata.characters do
69 local v, pl, pr = setup[i], nil, nil
70 if v then
71 pl, pr = v[1], v[2]
72 end
73 if pl and pl ~= 0 then chr.left_protruding = left *pl*factor end
74 if pr and pr ~= 0 then chr.right_protruding = right*pr*factor end
75 end
76 end
77 end
78end
79
80local specification = {
81 name = "protrusion",
82 description = "shift characters into the left and or right margin",
83 initializers = {
84 base = initializeprotrusion,
85 node = initializeprotrusion,
86 }
87}
88
89registerotffeature(specification)
90registerafmfeature(specification)
91
92
93
94fonts.expansions = fonts.expansions or { }
95fonts.expansions.setups = fonts.expansions.setups or { }
96local setups = fonts.expansions.setups
97
98setups['default'] = {
99
100 stretch = 2,
101 shrink = 2,
102 step = .5,
103 factor = 1,
104
105 [byte('A')] = 0.5, [byte('B')] = 0.7, [byte('C')] = 0.7, [byte('D')] = 0.5, [byte('E')] = 0.7,
106 [byte('F')] = 0.7, [byte('G')] = 0.5, [byte('H')] = 0.7, [byte('K')] = 0.7, [byte('M')] = 0.7,
107 [byte('N')] = 0.7, [byte('O')] = 0.5, [byte('P')] = 0.7, [byte('Q')] = 0.5, [byte('R')] = 0.7,
108 [byte('S')] = 0.7, [byte('U')] = 0.7, [byte('W')] = 0.7, [byte('Z')] = 0.7,
109 [byte('a')] = 0.7, [byte('b')] = 0.7, [byte('c')] = 0.7, [byte('d')] = 0.7, [byte('e')] = 0.7,
110 [byte('g')] = 0.7, [byte('h')] = 0.7, [byte('k')] = 0.7, [byte('m')] = 0.7, [byte('n')] = 0.7,
111 [byte('o')] = 0.7, [byte('p')] = 0.7, [byte('q')] = 0.7, [byte('s')] = 0.7, [byte('u')] = 0.7,
112 [byte('w')] = 0.7, [byte('z')] = 0.7,
113 [byte('2')] = 0.7, [byte('3')] = 0.7, [byte('6')] = 0.7, [byte('8')] = 0.7, [byte('9')] = 0.7,
114}
115
116local function initializeexpansion(tfmdata,value)
117 if value then
118 local setup = setups[value]
119 if setup then
120 local factor = setup.factor or 1
121 tfmdata.parameters.expansion = {
122 stretch = 10 * (setup.stretch or 0),
123 shrink = 10 * (setup.shrink or 0),
124 step = 10 * (setup.step or 0),
125 auto = true,
126 }
127 for i, chr in next, tfmdata.characters do
128 local v = setup[i]
129 if v and v ~= 0 then
130 chr.expansion_factor = v*factor
131 else
132 chr.expansion_factor = factor
133 end
134 end
135 end
136 end
137end
138
139local specification = {
140 name = "expansion",
141 description = "apply hz optimization",
142 initializers = {
143 base = initializeexpansion,
144 node = initializeexpansion,
145 }
146}
147
148registerotffeature(specification)
149registerafmfeature(specification)
150
151
152
153if not otf.features.normalize then
154
155 otf.features.normalize = function(t)
156 if t.rand then
157 t.rand = "random"
158 end
159 return t
160 end
161
162end
163
164
165
166function fonts.helpers.nametoslot(name)
167 local t = type(name)
168 if t == "string" then
169 local tfmdata = fonts.hashes.identifiers[currentfont()]
170 local shared = tfmdata and tfmdata.shared
171 local fntdata = shared and shared.rawdata
172 return fntdata and fntdata.resources.unicodes[name]
173 elseif t == "number" then
174 return n
175 end
176end
177
178
179
180
181
182
183
184
185
186
187fonts.encodings = fonts.encodings or { }
188local reencodings = { }
189fonts.encodings.reencodings = reencodings
190
191local function specialreencode(tfmdata,value)
192
193
194
195 local encoding = value and reencodings[value]
196 if encoding then
197 local temp = { }
198 local char = tfmdata.characters
199 for k, v in next, encoding do
200 temp[k] = char[v]
201 end
202 for k, v in next, temp do
203 char[k] = temp[k]
204 end
205
206
207 return string.format("reencoded:%s",value)
208 end
209end
210
211local function initialize(tfmdata,value)
212 tfmdata.postprocessors = tfmdata.postprocessors or { }
213 table.insert(tfmdata.postprocessors,
214 function(tfmdata)
215 return specialreencode(tfmdata,value)
216 end
217 )
218end
219
220registerotffeature {
221 name = "reencode",
222 description = "reencode characters",
223 manipulators = {
224 base = initialize,
225 node = initialize,
226 }
227}
228
229
230
231local function initialize(tfmdata,key,value)
232 if value then
233 tfmdata.mathparameters = nil
234 end
235end
236
237registerotffeature {
238 name = "ignoremathconstants",
239 description = "ignore math constants table",
240 initializers = {
241 base = initialize,
242 node = initialize,
243 }
244}
245 |