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