1if not modules then modules = { } end modules ['font-vir'] = {
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
9
12
13
14
15
16
17local next, setmetatable, getmetatable = next, setmetatable, getmetatable
18
19local allocate = utilities.storage.allocate
20local setmetatableindex = table.setmetatableindex
21local fastcopy = table.fastcopy
22
23local fonts = fonts
24local constructors = fonts.constructors
25local vf = constructors.handlers.vf
26vf.version = 1.000
27
28
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61local definers = fonts.definers
62local methods = definers.methods
63
64local variants = allocate()
65local combinations = { }
66local combiner = { }
67local whatever = allocate()
68local helpers = allocate()
69local predefined = fonts.helpers.commands
70
71methods.variants = variants
72vf.combinations = combinations
73vf.combiner = combiner
74vf.whatever = whatever
75vf.helpers = helpers
76vf.predefined = predefined
77
78setmetatableindex(whatever, function(t,k) local v = { } t[k] = v return v end)
79
80local function checkparameters(g,f)
81 if f and g and not g.parameters and #g.fonts > 0 then
82 local p = { }
83 for k,v in next, f.parameters do
84 p[k] = v
85 end
86 g.parameters = p
87 setmetatable(p, getmetatable(f.parameters))
88 end
89end
90
91function methods.install(tag, rules)
92 vf.combinations[tag] = rules
93 variants[tag] = function(specification)
94 return vf.combine(specification,tag)
95 end
96end
97
98local function combine_load(g,name)
99 return constructors.readanddefine(name or g.specification.name,g.specification.size)
100end
101
102local function combine_assign(g, name, from, to, start, force)
103 local f, id = combine_load(g,name)
104 if f and id then
105
106 if not from then from, to = 0, 0xFF00 end
107 if not to then to = from end
108 if not start then start = from end
109 local fc = f.characters
110 local gc = g.characters
111 local fd = f.descriptions
112 local gd = g.descriptions
113 local hn = #g.fonts+1
114 g.fonts[hn] = { id = id }
115 for i=from,to do
116 if fc[i] and (force or not gc[i]) then
117 gc[i] = fastcopy(fc[i],true)
118 gc[i].commands = { { "slot", hn, start } }
119 gd[i] = fd[i]
120 end
121 start = start + 1
122 end
123 checkparameters(g,f)
124 end
125end
126
127local function combine_process(g,list)
128 if list then
129 for _,v in next, list do
130 (combiner.commands[v[1]] or nop)(g,v)
131 end
132 end
133end
134
135local function combine_names(g,name,force)
136 local f, id = constructors.readanddefine(name,g.specification.size)
137 if f and id then
138 local fc = f.characters
139 local gc = g.characters
140 local fd = f.descriptions
141 local gd = g.descriptions
142 g.fonts[#g.fonts+1] = { id = id }
143 local hn = #g.fonts
144 for k, v in next, fc do
145 if force or not gc[k] then
146 gc[k] = fastcopy(v,true)
147 gc[k].commands = { { "slot", hn, k } }
148 gd[i] = fd[i]
149 end
150 end
151 checkparameters(g,f)
152 end
153end
154
155local combine_feature = function(g,v)
156 local key = v[2]
157 local value = v[3]
158 if key then
159 if value == nil then
160 value = true
161 end
162 local specification = g.specification
163 if specification then
164 local normalfeatures = specification.features.normal
165 if normalfeatures then
166 normalfeatures[key] = value
167 end
168 end
169 end
170end
171
172
173
174
175
176
177
178combiner.commands = allocate {
179 ["initialize"] = function(g,v) combine_assign (g,g.properties.name) end,
180 ["include-method"] = function(g,v) combine_process (g,combinations[v[2]]) end,
181
182 ["copy-range"] = function(g,v) combine_assign (g,v[2],v[3],v[4],v[5],true) end,
183 ["copy-char"] = function(g,v) combine_assign (g,v[2],v[3],v[3],v[4],true) end,
184 ["fallback-range"] = function(g,v) combine_assign (g,v[2],v[3],v[4],v[5],false) end,
185 ["fallback-char"] = function(g,v) combine_assign (g,v[2],v[3],v[3],v[4],false) end,
186 ["copy-names"] = function(g,v) combine_names (g,v[2],true) end,
187 ["fallback-names"] = function(g,v) combine_names (g,v[2],false) end,
188 ["feature"] = combine_feature,
189}
190
191function vf.combine(specification,tag)
192 local g = {
193 name = specification.name,
194 properties = {
195 virtualized = true,
196 },
197 fonts = {
198 },
199 characters = {
200 },
201 descriptions = {
202 },
203 specification = fastcopy(specification),
204 }
205 combine_process(g,combinations[tag])
206 return g
207end
208 |