1if not modules then modules = { } end modules [ ' good-mth ' ] = {
2 version = 1 . 000 ,
3 comment = " companion to font-lib.mkiv " ,
4 author = " Hans Hagen, PRAGMA-ADE, Hasselt NL " ,
5 copyright = " PRAGMA ADE / ConTeXt Development Team " ,
6 license = " see context related readme files "
7}
8
9local type , next = type , next
10local ceil = math . ceil
11
12local fonts = fonts
13
14local trace_goodies = false trackers . register ( " fonts.goodies " , function ( v ) trace_goodies = v end )
15local report_goodies = logs . reporter ( " fonts " , " goodies " )
16
17local registerotffeature = fonts . handlers . otf . features . register
18
19local fontgoodies = fonts . goodies or { }
20
21local fontcharacters = fonts . hashes . characters
22
23local nuts = nodes . nuts
24
25local setlink = nuts . setlink
26
27local nodepool = nuts . pool
28
29local new_kern = nodepool . kern
30local new_glyph = nodepool . glyph
31local new_hlist = nodepool . hlist
32local new_vlist = nodepool . vlist
33
34local insert_node_after = nuts . insert_after
35
36
37
38
39local function finalize ( tfmdata , feature , value )
40 mathematics . overloaddimensions ( tfmdata , tfmdata , value )
41end
42
43registerotffeature {
44 name = " mathdimensions " ,
45 description = " manipulate math dimensions " ,
46
47 manipulators = {
48 base = finalize ,
49 node = finalize ,
50 }
51}
52
53local function initialize ( goodies )
54 local mathgoodies = goodies . mathematics
55 if mathgoodies then
56 local virtuals = mathgoodies . virtuals
57 local mapfiles = mathgoodies . mapfiles
58 local maplines = mathgoodies . maplines
59 if virtuals then
60 for name , specification in next , virtuals do
61
62 mathematics . makefont ( name , specification , goodies )
63 end
64 end
65 if mapfiles then
66 for i = 1 , # mapfiles do
67 fonts . mappings . loadfile ( mapfiles [ i ] )
68 end
69 end
70 if maplines then
71 for i = 1 , # maplines do
72 fonts . mappings . loadline ( maplines [ i ] )
73 end
74 end
75 end
76end
77
78fontgoodies . register ( " mathematics " , initialize )
79
80local enabled = false directives . register ( " fontgoodies.mathkerning " , function ( v ) enabled = v end )
81
82local function initialize ( tfmdata )
83 if enabled and tfmdata . mathparameters then
84 local goodies = tfmdata . goodies
85 if goodies then
86 local characters = tfmdata . characters
87 if characters [ 0x1D44E ] then
88
89 for i = 1 , # goodies do
90 local mathgoodies = goodies [ i ] . mathematics
91 if mathgoodies then
92 local kerns = mathgoodies . kerns
93 if kerns then
94 for unicode , specification in next , kerns do
95 local chardata = characters [ unicode ]
96 if chardata and ( not chardata . mathkerns or specification . force ) then
97 chardata . mathkerns = specification
98 end
99 end
100 return
101 end
102 end
103 end
104 else
105 return
106 end
107 end
108 end
109end
110
111registerotffeature {
112 name = " mathkerns " ,
113 description = " math kerns " ,
114 default = true ,
115 initializers = {
116 base = initialize ,
117 node = initialize ,
118 }
119}
120
121
122
123
124
125local function initialize ( tfmdata )
126 local goodies = tfmdata . goodies
127 if goodies then
128 local shared = tfmdata . shared
129 for i = 1 , # goodies do
130 local mathgoodies = goodies [ i ] . mathematics
131 if mathgoodies then
132 local mathitalics = mathgoodies . italics
133 if mathitalics then
134 local properties = tfmdata . properties
135 if properties . setitalics then
136 mathitalics = mathitalics [ file . nameonly ( properties . name ) ] or mathitalics
137 if mathitalics then
138 if trace_goodies then
139 report_goodies ( " loading mathitalics for font %a " , properties . name )
140 end
141 local corrections = mathitalics . corrections
142 local defaultfactor = mathitalics . defaultfactor
143
144 if corrections then
145 fontgoodies . registerpostprocessor ( tfmdata , function ( tfmdata )
146
147 local properties = tfmdata . properties
148 local parameters = tfmdata . parameters
149 local characters = tfmdata . characters
150 properties . mathitalic_defaultfactor = defaultfactor
151 properties . mathitalic_defaultvalue = defaultfactor * parameters . quad
152 if trace_goodies then
153 report_goodies ( " assigning mathitalics for font %a " , properties . name )
154 end
155 local quad = parameters . quad
156 local hfactor = parameters . hfactor
157 for k , v in next , corrections do
158 local c = characters [ k ]
159 if c then
160 if v > -1 and v < 1 then
161 c . italic = v * quad
162 else
163 c . italic = v * hfactor
164 end
165 else
166 report_goodies ( " invalid mathitalics entry %U for font %a " , k , properties . name )
167 end
168 end
169 end )
170 end
171 return
172 end
173 end
174 end
175 end
176 end
177 end
178end
179
180registerotffeature {
181 name = " mathitalics " ,
182 description = " additional math italic corrections " ,
183
184 initializers = {
185 base = initialize ,
186 node = initialize ,
187 }
188}
189
190
191
192local function mathradicalaction ( n , h , v , font , mchar , echar )
193 local characters = fontcharacters [ font ]
194 local mchardata = characters [ mchar ]
195 local echardata = characters [ echar ]
196 local ewidth = echardata . width
197 local mwidth = mchardata . width
198 local delta = h - ewidth
199 local glyph = new_glyph ( font , echar )
200 local head = glyph
201 if delta > 0 then
202 local count = ceil ( delta / mwidth )
203 local kern = ( delta - count * mwidth ) / count
204 for i = 1 , count do
205 local k = new_kern ( kern )
206 local g = new_glyph ( font , mchar )
207 setlink ( k , head )
208 setlink ( g , k )
209 head = g
210 end
211 end
212 local height = mchardata . height
213 local list = new_hlist ( head )
214 local kern = new_kern ( height - v )
215 list = setlink ( kern , list )
216 local list = new_vlist ( kern )
217 insert_node_after ( n , n , list )
218end
219
220local function mathhruleaction ( n , h , v , font , bchar , mchar , echar )
221 local characters = fontcharacters [ font ]
222 local bchardata = characters [ bchar ]
223 local mchardata = characters [ mchar ]
224 local echardata = characters [ echar ]
225 local bwidth = bchardata . width
226 local mwidth = mchardata . width
227 local ewidth = echardata . width
228 local delta = h - ewidth - bwidth
229 local glyph = new_glyph ( font , echar )
230 local head = glyph
231 if delta > 0 then
232 local count = ceil ( delta / mwidth )
233 local kern = ( delta - count * mwidth ) / ( count + 1 )
234 for i = 1 , count do
235 local k = new_kern ( kern )
236 local g = new_glyph ( font , mchar )
237 setlink ( k , head )
238 setlink ( g , k )
239 head = g
240 end
241 local k = new_kern ( kern )
242 setlink ( k , head )
243 head = k
244 end
245 local g = new_glyph ( font , bchar )
246 setlink ( g , head )
247 head = g
248 local height = mchardata . height
249 local list = new_hlist ( head )
250 local kern = new_kern ( height - v )
251 list = setlink ( kern , list )
252 local list = new_vlist ( kern )
253 insert_node_after ( n , n , list )
254end
255
256local function initialize ( tfmdata )
257 local goodies = tfmdata . goodies
258 if goodies then
259 local resources = tfmdata . resources
260 local ruledata = { }
261 for i = 1 , # goodies do
262 local mathematics = goodies [ i ] . mathematics
263 if mathematics then
264 local rules = mathematics . rules
265 if rules then
266 for tag , name in next , rules do
267 ruledata [ tag ] = name
268 end
269 end
270 end
271 end
272 if next ( ruledata ) then
273 local characters = tfmdata . characters
274 local unicodes = resources . unicodes
275 if characters and unicodes then
276 local mathruleactions = resources . mathruleactions
277 if not mathruleactions then
278 mathruleactions = { }
279 resources . mathruleactions = mathruleactions
280 end
281
282 local mchar = unicodes [ ruledata [ " radical.extender " ] or false ]
283 local echar = unicodes [ ruledata [ " radical.end " ] or false ]
284 if mchar and echar then
285 mathruleactions . radicalaction = function ( n , h , v , font )
286 mathradicalaction ( n , h , v , font , mchar , echar )
287 end
288 end
289
290 local bchar = unicodes [ ruledata [ " hrule.begin " ] or false ]
291 local mchar = unicodes [ ruledata [ " hrule.extender " ] or false ]
292 local echar = unicodes [ ruledata [ " hrule.end " ] or false ]
293 if bchar and mchar and echar then
294 mathruleactions . hruleaction = function ( n , h , v , font )
295 mathhruleaction ( n , h , v , font , bchar , mchar , echar )
296 end
297 end
298
299
300 end
301 end
302 end
303end
304
305registerotffeature {
306 name = " mathrules " ,
307 description = " check math rules " ,
308 default = true ,
309 initializers = {
310 base = initialize ,
311 node = initialize ,
312 }
313}
314 |