font-vfc.lmt /size: 6813 b    last modification: 2023-12-21 09:44
1if not modules then modules = { } end modules ['font-vfc'] = {
2    version   = 1.001,
3    comment   = "companion to font-ini.mkiv and hand-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
9local select, type = select, type
10local insert = table.insert
11
12local fonts             = fonts
13local helpers           = fonts.helpers
14
15local setmetatableindex = table.setmetatableindex
16----- makeweak          = table.makeweak
17
18-- Helpers dealing with virtual fonts: beware, these are final values so
19-- don't change the content of tables fetched from here!
20
21local pushcommand  = { "push" }
22local popcommand   = { "pop" }
23local dummycommand = { "comment" }
24
25local slotcommand = setmetatableindex(function(t,k)
26    local v = setmetatableindex(function(tt,kk)
27        local vv = { "slot", k, kk }
28        tt[kk] = vv
29        return vv
30    end)
31    t[k] = v
32    return v
33end)
34
35function helpers.prependcommands(commands,...)
36    insert(commands,1,pushcommand)
37    for i=select("#",...),1,-1 do
38        local s = (select(i,...))
39        if s then
40            insert(commands,1,s)
41        end
42    end
43    insert(commands,popcommand)
44    return commands
45end
46
47function helpers.appendcommands(commands,...)
48    insert(commands,1,pushcommand)
49    insert(commands,popcommand)
50    for i=1,select("#",...) do
51        local s = (select(i,...))
52        if s then
53            insert(commands,s)
54        end
55    end
56    return commands
57end
58
59function helpers.prependcommandtable(commands,t)
60    insert(commands,1,pushcommand)
61    for i=#t,1,-1 do
62        local s = t[i]
63        if s then
64            insert(commands,1,s)
65        end
66    end
67    insert(commands,popcommand)
68    return commands
69end
70
71function helpers.appendcommandtable(commands,t)
72    insert(commands,1,pushcommand)
73    insert(commands,popcommand)
74    for i=1,#t do
75        local s = t[i]
76        if s then
77            insert(commands,s)
78        end
79    end
80    return commands
81end
82
83helpers.commands = utilities.storage.allocate {
84    char  = setmetatableindex(function(t,k) local v = { "char",  k } t[k] = v return v end),
85    stay  = setmetatableindex(function(t,k) local v = { "stay",  k } t[k] = v return v end),
86    right = setmetatableindex(function(t,k) local v = { "right", k } t[k] = v return v end),
87    left  = setmetatableindex(function(t,k) local v = { "left",  k } t[k] = v return v end),
88    down  = setmetatableindex(function(t,k) local v = { "down",  k } t[k] = v return v end),
89    up    = setmetatableindex(function(t,k) local v = { "up",    k } t[k] = v return v end),
90    push  = pushcommand,
91    pop   = popcommand,
92    dummy = dummycommand,
93    slot  = slotcommand,
94}
95
96local codeinjections = backends.codeinjections
97local vfstartcolor   = codeinjections.vfstartcolor
98local vfstopcolor    = codeinjections.vfstopcolor
99----- vfliteral      = codeinjections.vfliteral
100
101helpers.vfinjectors = {
102 -- startcolor = function(h,v,packet) codeinjections.vfstartcolor(h,v,packet) end,
103 -- stopcolor  = function(h,v,packet) codeinjections.vfstartcolor(h,v,packet) end,
104 -- literal    = function(h,v,packet) codeinjections.vfliteral   (h,v,packer) end,
105    startcolor = function(h,v,packet) vfstartcolor(h,v,packet) end,
106    stopcolor  = function(h,v,packet) vfstopcolor (h,v,packet) end,
107 -- literal    = function(h,v,packet) vfliteral   (h,v,packer) end,
108}
109
110updaters.register("backends.injections.latebindings",function()
111    vfstartcolor = backends.codeinjections.vfstartcolor
112    vfstopcolor  = backends.codeinjections.vfstopcolor
113 -- vfliteral    = backends.codeinjections.vfliteral
114end)
115
116-- maybe round()
117
118local defaultline = 16384
119
120helpers.vfspecials = {
121
122    backgrounds = setmetatableindex(function(t,h)
123        local v = setmetatableindex(function(t,d)
124            local v = setmetatableindex(function(t,w)
125                local v = { "frame", w, h, d, defaultline, false, false }
126                t[w] = v
127                return v
128            end)
129            t[d] = v
130            return v
131        end)
132        t[h] = v
133        return v
134    end),
135
136    outlines = setmetatableindex(function(t,h)
137        local v = setmetatableindex(function(t,d)
138            local v = setmetatableindex(function(t,w)
139                local v = { "frame", w, h, d, defaultline, true, false }
140                t[w] = v
141                return v
142            end)
143            t[d] = v
144            return v
145        end)
146        t[h] = v
147        return v
148    end),
149
150}
151
152-- In the past we only copied when we had something that got scaled but the problem
153-- is that we then run into issues when we extend a commands in the parent. This
154-- needs checking. When we go to glyph scaling, this can go away.
155--
156-- The alternative is to work with unscaled values and always do scaling at the
157-- TeX end. So, then we need accessors instead of tables and we also need to check
158-- all the context code: where do we access values?
159--
160-- On the other hand, in glyph scale mode we hardly do any scaling so we seldom
161-- call the next one.
162--
163-- What if we use named fields: then we can scale by field name.
164
165local scaled = {
166    right  = true,
167    down   = true,
168    left   = true,
169    right  = true,
170    offset = true,
171    rule   = true,
172    char   = false,
173    font   = false,
174    slot   = false,
175    use    = false,
176    push   = false,
177    pop    = false,
178    lua    = false,
179    -- obsolete
180    node   = false,
181    -- additional ones are never scaled (color etc)
182}
183
184-- normally we don't have these, and if so, only in old school fonts
185-- in which case we don't have extensions so ...
186
187function helpers.scalecommands(list,hdelta,vdelta)
188    local n = #list
189    for i=1,n do
190        local cmd = list[i]
191        if scaled[cmd[1]] then
192            local result = { }
193            for i=1,n do
194                local cmd = list[i]
195                local key = cmd[1]
196                if key == "right" or key == "left" then
197                    result[i] = { key, cmd[2]*hdelta }
198                elseif key == "down" or key == "up" then
199                    result[i] = { key, cmd[2]*vdelta }
200                elseif key == "offset" then
201                    result[i] = { key, cmd[2]*hdelta, cmd[3]*vdelta, cmd[4], cmd[5], cmd[6] }
202                elseif key == "rule" then
203                    result[i] = { key, cmd[2]*hdelta, cmd[3]*vdelta }
204                elseif key == "line" then
205                    result[i] = { key, cmd[2]*hdelta, cmd[3]*vdelta, cmd[4]*vdelta, cmd[5] }
206             -- elseif key == "frame" then
207             --     result[i] = cmd -- already scaled, for now
208                else
209                    result[i] = cmd -- shared since in cache and untouched
210                end
211            end
212            return result
213        end
214    end
215    return list
216end
217