1if not modules then modules = { } end modules ['good-gen'] = {
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 = type, next
12local lower = string.lower
13local filesuffix, replacesuffix = file.suffix, file.replacesuffix
14local fonts = fonts
15
16
17
18
19local allocate = utilities.storage.allocate
20local texsp = tex.sp
21local fontgoodies = fonts.goodies or { }
22local findfile = resolvers.findfile
23
24
25local typefaces = fonts.typefaces or { }
26fonts.typefaces = typefaces
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44local function initialize(goodies)
45 local files = goodies.files
46 if files then
47 fonts.names.register(files)
48 end
49end
50
51fontgoodies.register("files", initialize)
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67local function initialize(goodies)
68 local typefaces = goodies.typefaces
69 if typefaces then
70 local ft = fonts.typefaces
71 for k, v in next, typefaces do
72 ft[k] = v
73 end
74 end
75end
76
77fontgoodies.register("typefaces", initialize)
78
79local compositions = { }
80
81function fontgoodies.getcompositions(tfmdata)
82 return compositions[file.nameonly(tfmdata.properties.filename or "")]
83end
84
85local function initialize(goodies)
86 local gc = goodies.compositions
87 if gc then
88 for k, v in next, gc do
89 compositions[k] = v
90 end
91 end
92end
93
94fontgoodies.register("compositions", initialize)
95
96
97
98local treatmentdata = fonts.treatments.data
99
100local function initialize(goodies)
101 local treatments = goodies.treatments
102 if treatments then
103 for name, data in next, treatments do
104 treatmentdata[name] = data
105 end
106 end
107end
108
109fontgoodies.register("treatments", initialize)
110
111local filenames = fontgoodies.filenames or allocate()
112fontgoodies.filenames = filenames
113
114local filedata = filenames.data or allocate()
115filenames.data = filedata
116
117local function initialize(goodies)
118 local fn = goodies.filenames
119 if fn then
120 for usedname, alternativenames in next, fn do
121 filedata[usedname] = alternativenames
122 end
123 end
124end
125
126fontgoodies.register("filenames", initialize)
127
128function fontgoodies.filenames.resolve(name)
129 local fd = filedata[name]
130 if fd and findfile(name) == "" then
131 for i=1,#fd do
132 local fn = fd[i]
133 if findfile(fn) ~= "" then
134 return fn
135 end
136 end
137 elseif filesuffix(name) == "any" then
138
139
140 local sequence = fonts.readers.sequence
141 for i=1,#sequence do
142 local fn = replacesuffix(name,sequence[i])
143 if findfile(fn) ~= "" then
144 return fn
145 end
146 end
147 else
148
149 end
150 return name
151end
152
153local designsizes = fontgoodies.designsizes or allocate()
154fontgoodies.designsizes = designsizes
155
156local designdata = designsizes.data or allocate()
157designsizes.data = designdata
158
159local function initialize(goodies)
160 local gd = goodies.designsizes
161 if gd then
162 for name, data in next, gd do
163 local ranges = { }
164 for size, file in next, data do
165 if size ~= "default" then
166 ranges[#ranges+1] = { texsp(size), file }
167 end
168 end
169 table.sort(ranges,function(a,b) return a[1] < b[1] end)
170 designdata[lower(name)] = {
171 default = data.default,
172 ranges = ranges,
173 }
174 end
175 end
176end
177
178fontgoodies.register("designsizes", initialize)
179
180function fontgoodies.designsizes.register(name,size,specification)
181 local d = designdata[name]
182 if not d then
183 d = {
184 ranges = { },
185 default = nil,
186 }
187 designdata[name] = d
188 end
189 if size == "default" then
190 d.default = specification
191 else
192 if type(size) == "string" then
193 size = texsp(size)
194 end
195 local ranges = d.ranges
196 ranges[#ranges+1] = { size, specification }
197 end
198end
199
200function fontgoodies.designsizes.filename(name,spec,size)
201 local data = designdata[lower(name)]
202 if data then
203 if not spec or spec == "" or spec == "default" then
204 return data.default
205 elseif spec == "auto" then
206 local ranges = data.ranges
207 if ranges then
208 for i=1,#ranges do
209 local r = ranges[i]
210 if r[1] >= size then
211 return r[2]
212 end
213 end
214 end
215 return data.default or (ranges and ranges[#ranges][2])
216 end
217 end
218end
219 |