1if not modules then modules = { } end modules [ ' font-fbk ' ] = {
2 version = 1 . 001 ,
3 comment = " companion to font-ini.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 cos , tan , rad , format = math . cos , math . tan , math . rad , string . format
10local utfbyte , utfchar = utf . byte , utf . char
11local next = next
12
13
16
17local trace_visualize = false trackers . register ( " fonts.composing.visualize " , function ( v ) trace_visualize = v end )
18local trace_define = false trackers . register ( " fonts.composing.define " , function ( v ) trace_define = v end )
19
20local report = logs . reporter ( " fonts " , " combining " )
21
22local allocate = utilities . storage . allocate
23
24local fonts = fonts
25local handlers = fonts . handlers
26local constructors = fonts . constructors
27local helpers = fonts . helpers
28
29local otf = handlers . otf
30local afm = handlers . afm
31local registerotffeature = otf . features . register
32local registerafmfeature = afm . features . register
33
34local addotffeature = otf . addfeature
35
36local unicodecharacters = characters . data
37local unicodefallbacks = characters . fallbacks
38
39local vfcommands = helpers . commands
40local charcommand = vfcommands . char
41local rightcommand = vfcommands . right
42local downcommand = vfcommands . down
43local upcommand = vfcommands . up
44local push = vfcommands . push
45local pop = vfcommands . pop
46
47local force_combining = false
48local fraction = 0 . 15
49
50
51
52
53local function composecharacters ( tfmdata )
54
55 local characters = tfmdata . characters
56 local descriptions = tfmdata . descriptions
57 local parameters = tfmdata . parameters
58 local properties = tfmdata . properties
59 local Xdesc = descriptions [ utfbyte ( " X " ) ]
60 local xdesc = descriptions [ utfbyte ( " x " ) ]
61 if Xdesc and xdesc then
62 local scale = parameters . factor or 1
63 local deltaxheight = scale * ( Xdesc . boundingbox [ 4 ] - xdesc . boundingbox [ 4 ] )
64 local extraxheight = fraction * deltaxheight
65 local italicfactor = parameters . italicfactor or 0
66 local red , green , blue , black
67 if trace_visualize then
68 red = { " startcolor " , " red " }
69 green = { " startcolor " , " green " }
70 blue = { " startcolor " , " blue " }
71 black = { " stopcolor " }
72 end
73 local compose = fonts . goodies . getcompositions ( tfmdata )
74 if compose and trace_visualize then
75 report ( " using compose information from goodies file " )
76 end
77 local done = false
78 for i , c in next , unicodecharacters do
79 if force_combining or not characters [ i ] then
80 local s = c . specials
81 if s and s [ 1 ] = = ' char ' then
82 local chr = s [ 2 ]
83 local charschr = characters [ chr ]
84 if charschr then
85 local cc = c . category
86 if cc = = ' ll ' or cc = = ' lu ' or cc = = ' lt ' then
87 local acc = s [ 3 ]
88 local t = { }
89 for k , v in next , charschr do
90 if k ~ = " commands " then
91 t [ k ] = v
92 end
93 end
94 local charsacc = characters [ acc ]
95
96
97
98
99
100
101
102
103 if not charsacc then
104 acc = unicodefallbacks [ acc ]
105 charsacc = acc and characters [ acc ]
106 end
107 local chr_t = charcommand [ chr ]
108 if charsacc then
109 if trace_define then
110 report ( " composed %C, base %C, accent %C " , i , chr , acc )
111 end
112 local acc_t = charcommand [ acc ]
113 local cb = descriptions [ chr ] . boundingbox
114 local ab = descriptions [ acc ] . boundingbox
115
116 if cb and ab then
117 local c_llx = scale * cb [ 1 ]
118 local c_lly = scale * cb [ 2 ]
119 local c_urx = scale * cb [ 3 ]
120 local c_ury = scale * cb [ 4 ]
121 local a_llx = scale * ab [ 1 ]
122 local a_lly = scale * ab [ 2 ]
123 local a_urx = scale * ab [ 3 ]
124 local a_ury = scale * ab [ 4 ]
125 local done = false
126 if compose then
127 local i_compose = compose [ i ]
128 local i_anchored = i_compose and i_compose . anchored
129 if i_anchored then
130 local c_compose = compose [ chr ]
131 local a_compose = compose [ acc ]
132 local c_anchors = c_compose and c_compose . anchors
133 local a_anchors = a_compose and a_compose . anchors
134 if c_anchors and a_anchors then
135 local c_anchor = c_anchors [ i_anchored ]
136 local a_anchor = a_anchors [ i_anchored ]
137 if c_anchor and a_anchor then
138 local cx = c_anchor . x or 0
139 local cy = c_anchor . y or 0
140 local ax = a_anchor . x or 0
141 local ay = a_anchor . y or 0
142 local dx = cx - ax
143 local dy = cy - ay
144 if trace_define then
145 report ( " building %C from %C and %C " , i , chr , acc )
146 report ( " boundingbox: " )
147 report ( " chr: %3i %3i %3i %3i " , unpack ( cb ) )
148 report ( " acc: %3i %3i %3i %3i " , unpack ( ab ) )
149 report ( " anchors: " )
150 report ( " chr: %3i %3i " , cx , cy )
151 report ( " acc: %3i %3i " , ax , ay )
152 report ( " delta: " )
153 report ( " %s: %3i %3i " , i_anchored , dx , dy )
154 end
155 local right = rightcommand [ scale * dx ]
156 local down = upcommand [ scale * dy ]
157 if trace_visualize then
158 t . commands = {
159 push , right , down ,
160 green , acc_t , black ,
161 pop , chr_t ,
162 }
163 else
164 t . commands = {
165 push , right , down ,
166 acc_t , pop , chr_t ,
167 }
168 end
169 done = true
170 end
171 end
172 end
173 end
174 if not done then
175
176 local dx = ( c_urx - a_urx - a_llx + c_llx ) / 2
177 local dd = ( c_urx - c_llx ) * italicfactor
178 if a_ury < 0 then
179 local right = rightcommand [ dx - dd ]
180 if trace_visualize then
181 t . commands = {
182 push , right , red , acc_t ,
183 black , pop , chr_t ,
184 }
185 else
186 t . commands = {
187 push , right , acc_t , pop ,
188 chr_t ,
189 }
190 end
191 t . depth = a_ury
192 elseif c_ury > a_lly then
193 local dy
194 if compose then
195
196
197 dy = compose [ i ]
198 if dy then
199 dy = dy . dy
200 end
201 if not dy then
202 dy = compose [ acc ]
203 if dy then
204 dy = dy and dy . dy
205 end
206 end
207 if not dy then
208 dy = compose . dy
209 end
210 if not dy then
211 dy = - deltaxheight + extraxheight
212 elseif dy > -1 . 5 and dy < 1 . 5 then
213
214 dy = - dy * deltaxheight
215 else
216
217 dy = - dy * scale
218 end
219 else
220 dy = - deltaxheight + extraxheight
221 end
222 t . height = a_ury - dy
223 local right = rightcommand [ dx + dd ]
224 local down = downcommand [ dy ]
225 if trace_visualize then
226 t . commands = {
227 push , right , down , green ,
228 acc_t , black , pop , chr_t ,
229 }
230 else
231 t . commands = {
232 push , right , down , acc_t ,
233 pop , chr_t ,
234 }
235 end
236 else
237 local right = rightcommand [ dx + dd ]
238 if trace_visualize then
239 t . commands = {
240 push , right , blue , acc_t ,
241 black , pop , chr_t ,
242 }
243 else
244 t . commands = {
245 push , right , acc_t , pop ,
246 chr_t ,
247 }
248 end
249 t . height = a_ury
250 end
251 end
252 else
253 t . commands = {
254 chr_t ,
255 }
256 end
257 else
258 if trace_define then
259 report ( " %C becomes simplified %C " , i , chr )
260 end
261 t . commands = {
262 chr_t ,
263 }
264 end
265 done = true
266 characters [ i ] = t
267 local d = { }
268 for k , v in next , descriptions [ chr ] do
269 d [ k ] = v
270 end
271 descriptions [ i ] = d
272 end
273 end
274 end
275 end
276 end
277 end
278end
279
280local specification = {
281 name = " compose " ,
282 description = " additional composed characters " ,
283 manipulators = {
284 base = composecharacters ,
285 node = composecharacters ,
286 }
287}
288
289registerotffeature ( specification )
290registerafmfeature ( specification )
291
292addotffeature {
293 name = " char-ligatures " ,
294 type = " ligature " ,
295 data = characters . splits . char ,
296 order = { " char-ligatures " } ,
297 prepend = true ,
298}
299
300addotffeature {
301 name = " compat-ligatures " ,
302 type = " ligature " ,
303 data = characters . splits . compat ,
304 order = { " compat-ligatures " } ,
305 prepend = true ,
306}
307
308registerotffeature {
309 name = ' char-ligatures ' ,
310 description = ' unicode char specials to ligatures ' ,
311}
312
313registerotffeature {
314 name = ' compat-ligatures ' ,
315 description = ' unicode compat specials to ligatures ' ,
316}
317
318
319
320fonts . helpers . composecharacters = composecharacters
321
322
323
324
325
326do
327
328 local vf = handlers . vf
329 local commands = vf . combiner . commands
330
331 vf . helpers . composecharacters = composecharacters
332
333 commands [ " compose.trace.enable " ] = function ( ) trace_visualize = true end
334 commands [ " compose.trace.disable " ] = function ( ) trace_visualize = false end
335 commands [ " compose.force.enable " ] = function ( ) force_combining = true end
336 commands [ " compose.force.disable " ] = function ( ) force_combining = false end
337
338 commands [ " compose.trace.set " ] = function ( g , v )
339 if v [ 2 ] = = nil then
340 trace_visualize = true
341 else
342 trace_visualize = v [ 2 ]
343 end
344 end
345
346 commands [ " compose.apply " ] = function ( g , v )
347 composecharacters ( g )
348 end
349
350end
351 |