1if not modules then modules = { } end modules ['font-imp-reorder'] = {
2 version = 1.001,
3 comment = "companion to font-ini.mkiv and hand-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
9if not context then return end
10
11local next = next
12local find = string.find
13local sortedhash, sortedkeys, sort = table.sortedhash, table.sortedkeys, table.sort
14
15local fonts = fonts
16local otf = fonts.handlers.otf
17local registerotffeature = otf.features.register
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34local trace_reorder = trackers.register("fonts.reorderlookups",function(v) trace_reorder = v end)
35local report_reorder = logs.reporter("fonts","reorder")
36
37local vectors = { }
38otf.vectors = vectors
39
40vectors.arab = {
41 gsub = {
42 ccmp = 1,
43 isol = 2,
44 fina = 3,
45 medi = 4,
46 init = 5,
47 rlig = 6,
48 rclt = 7,
49 calt = 8,
50 liga = 9,
51 dlig = 10,
52 cswh = 11,
53 mset = 12,
54 },
55 gpos = {
56 curs = 1,
57 kern = 2,
58 mark = 3,
59 mkmk = 4,
60 },
61}
62
63local function compare(a,b)
64 local what_a = a.what
65 local what_b = b.what
66 if what_a ~= what_b then
67 return a.index < b.index
68 end
69 local when_a = a.when
70 local when_b = b.when
71 if when_a == when_b then
72 return a.index < b.index
73 else
74 return when_a < when_b
75 end
76end
77
78function otf.reorderlookups(tfmdata,vector)
79 local order = vectors[vector]
80 if not order then
81 return
82 end
83 local oldsequences = tfmdata.resources.sequences
84 if oldsequences then
85 local sequences = { }
86 for i=1,#oldsequences do
87 sequences[i] = oldsequences[i]
88 end
89 for i=1,#sequences do
90 local s = sequences[i]
91 local features = s.features
92 local kind = s.type
93 local index = s.index
94 if features then
95 local when
96 local what
97 for feature in sortedhash(features) do
98 if not what then
99 what = find(kind,"^gsub") and "gsub" or "gpos"
100 end
101
102 if not newwhen then
103
104 elseif not when then
105 when = newwhen
106 elseif newwhen < when then
107 when = newwhen
108 end
109 end
110 s.ondex = s.index
111 s.index = i
112 s.what = what == "gsub" and 1 or 2
113 s.when = when or 99
114 else
115 s.ondex = s.index
116 s.index = i
117 s.what = 1
118 s.when = 99
119 end
120 end
121 sort(sequences,compare)
122 local swapped = 0
123 for i=1,#sequences do
124 local sequence = sequences[i]
125 local features = sequence.features
126 if features then
127 local index = sequence.index
128 if index ~= i then
129 swapped = swapped + 1
130 end
131 if trace_reorder then
132 if swapped == 1 then
133 report_reorder()
134 report_reorder("start swapping lookups in font %!font:name!",tfmdata)
135 report_reorder()
136 report_reorder("gsub order: % t",table.swapped(order.gsub))
137 report_reorder("gpos order: % t",table.swapped(order.gpos))
138 report_reorder()
139 end
140 report_reorder("%03i : lookup %03i, type %s, sorted %2i, moved %s, % t",
141 i,index,sequence.what == 1 and "gsub" or "gpos",sequence.when or 99,
142 (index > i and "-") or (index < i and "+") or "=",sortedkeys(features))
143 end
144 end
145 sequence.what = nil
146 sequence.when = nil
147 sequence.index = sequence.ondex
148 end
149 if swapped > 0 then
150 if trace_reorder then
151 report_reorder()
152 report_reorder("stop swapping lookups, %i lookups swapped",swapped)
153 report_reorder()
154 end
155 tfmdata.shared.reorderedsequences = sequences
156 end
157 end
158end
159
160
161
162local function initialize(tfmdata,key,value)
163 if value then
164 otf.reorderlookups(tfmdata,value)
165 end
166end
167
168registerotffeature {
169 name = "reorderlookups",
170 description = "reorder lookups",
171 manipulators = {
172 base = initialize,
173 node = initialize,
174 }
175}
176 |