1if not modules then modules = { } end modules ['good-ctx'] = {
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
9
10
11local type, next, tonumber = type, next, tonumber
12local find, splitup = string.find, string.splitup
13
14local fonts = fonts
15local nodes = nodes
16local attributes = attributes
17
18
19
20
21local allocate = utilities.storage.allocate
22local setmetatableindex = table.setmetatableindex
23
24local implement = interfaces.implement
25
26local registerotffeature = fonts.handlers.otf.features.register
27
28
29
30local fontgoodies = fonts.goodies or { }
31
32local nuts = nodes.nuts
33local tonut = nuts.tonut
34local getattr = nuts.getattr
35local getprop = nuts.getprop
36local nextglyph = nuts.traversers.glyph
37
38
39
40local colorschemes = fontgoodies.colorschemes or allocate { }
41fontgoodies.colorschemes = colorschemes
42colorschemes.data = colorschemes.data or { }
43
44local privatestoo = true
45
46local function setcolorscheme(tfmdata,scheme)
47 if type(scheme) == "string" then
48 local goodies = tfmdata.goodies
49
50 if goodies then
51 local what
52 for i=1,#goodies do
53
54 local g = goodies[i]
55 what = g.colorschemes and g.colorschemes[scheme] or what
56 end
57 if type(what) == "table" then
58
59
60 local hash = tfmdata.resources.unicodes
61 local reverse = { }
62 local characters = tfmdata.characters
63 for i=1,#what do
64 local w = what[i]
65 local force = w.force
66 local list = w.list or w
67 for j=1,#list do
68 local name = list[j]
69 local kind = type(name)
70 if name == "*" then
71
72 for _, unicode in next, hash do
73 reverse[unicode] = i
74 end
75 elseif kind == "number" then
76 reverse[name] = i
77 elseif kind ~= "string" then
78
79 elseif find(name,":",1,true) then
80 local start, stop = splitup(name,":")
81 start = tonumber(start)
82 stop = tonumber(stop)
83 if start and stop then
84
85
86
87 if force then
88 for unicode=start,stop do
89 reverse[unicode] = i
90 end
91 else
92 for unicode=start,stop do
93 if characters[unicode] then
94 reverse[unicode] = i
95 end
96 end
97 end
98 end
99 else
100 local unicode = hash[name]
101 if unicode then
102 reverse[unicode] = i
103 end
104 end
105 end
106 end
107 if privatestoo then
108 local privateoffset = fonts.constructors.privateoffset
109 local descriptions = tfmdata.descriptions
110 for unicode, data in next, characters do
111 if unicode >= privateoffset then
112 if not reverse[unicode] then
113 local d = descriptions[unicode]
114 if d then
115 local u = d.unicode
116 if u then
117 local r = reverse[u]
118 if r then
119 reverse[unicode] = r
120 end
121 end
122 end
123 end
124 end
125 end
126 end
127 tfmdata.properties.colorscheme = reverse
128 return
129 end
130 end
131 end
132 tfmdata.properties.colorscheme = false
133end
134
135local fontproperties = fonts.hashes.properties
136local a_colorscheme = attributes.private('colorscheme')
137local setnodecolor = nodes.tracers.colors.set
138local cache = { }
139
140setmetatableindex(cache,function(t,a)
141 local v = { }
142 setmetatableindex(v,function(t,c)
143 local v = "colorscheme:" .. a .. ":" .. c
144 t[c] = v
145 return v
146 end)
147 t[a]= v
148 return v
149end)
150
151function colorschemes.coloring(head)
152 local lastfont = nil
153 local lastattr = nil
154 local lastcache = nil
155 local lastscheme = nil
156 for n, char, f in nextglyph, head do
157 local a = getattr(n,a_colorscheme)
158 if a then
159 if f ~= lastfont then
160 lastfont = f
161 lastscheme = fontproperties[f].colorscheme
162 if not lastscheme then
163 local p = getprop(n, "original")
164 if p then
165 lastfont = p.font
166 lastscheme = fontproperties[lastfont].colorscheme
167 end
168 end
169 end
170 if a ~= lastattr then
171 lastattr = a
172 lastcache = cache[a]
173 end
174 if lastscheme then
175 local sc = lastscheme[char]
176 if sc then
177
178 setnodecolor(n,lastcache[sc])
179 end
180 end
181 end
182 end
183 return head
184end
185
186function colorschemes.enable()
187 nodes.tasks.enableaction("processors","fonts.goodies.colorschemes.coloring")
188 function colorschemes.enable() end
189end
190
191registerotffeature {
192 name = "colorscheme",
193 description = "goodie color scheme",
194 initializers = {
195 base = setcolorscheme,
196 node = setcolorscheme,
197 }
198}
199
200
201
202
203
204
205local function setkeepligatures(tfmdata)
206 if not tfmdata.properties.keptligatures then
207 local goodies = tfmdata.goodies
208 if goodies then
209 for i=1,#goodies do
210 local g = goodies[i]
211 local letterspacing = g.letterspacing
212 if letterspacing then
213 local keptligatures = letterspacing.keptligatures
214 if keptligatures then
215 local unicodes = tfmdata.resources.unicodes
216 local hash = { }
217 for k, v in next, keptligatures do
218 local u = unicodes[k]
219 if u then
220 hash[u] = true
221 else
222
223 end
224 end
225 tfmdata.properties.keptligatures = hash
226 end
227 end
228 end
229 end
230 end
231end
232
233registerotffeature {
234 name = "keepligatures",
235 description = "keep ligatures in letterspacing",
236 initializers = {
237 base = setkeepligatures,
238 node = setkeepligatures,
239 }
240}
241
242if implement then
243
244 implement {
245 name = "enablefontcolorschemes",
246 onlyonce = true,
247 actions = colorschemes.enable,
248 overload = true,
249 }
250
251end
252 |