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