back-res.lmt /size: 7335 b    last modification: 2023-12-21 09:44
1if not modules then modules = { } end modules ['back-res'] = {
2    version   = 1.001,
3    comment   = "companion to back-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 context         = context
10
11local trace           = false  trackers.register("backend", function(v) trace = v end)
12local report          = logs.reporter("backend")
13
14local scanners        = tokens.scanners
15local scankeyword     = scanners.keyword
16local scaninteger     = scanners.integer
17local scanstring      = scanners.string
18local scandimension   = scanners.dimension
19local scanword        = scanners.word
20local scanwhd         = scanners.whd
21
22local implement       = interfaces.implement
23local constants       = interfaces.constants
24local variables       = interfaces.variables
25
26local values          = tokens.values
27----- dimension_value = values.dimension
28local cardinal_value  = values.cardinal
29----- direct_value    = values.direct
30
31-- A box resource has an index. This happens to be an object number due to the pdf
32-- backend but in fact it's an abstraction. This is why we have explicit fetchers.
33-- The internal number (as in \Fm123) is yet another number.
34
35-- this will change:
36--
37-- tex.*            : arglist, as in luatex
38-- tex.boxresources : table
39
40local codeinjections = backends.codeinjections
41local nodeinjections = backends.nodeinjections
42
43local savebox = function(...) return codeinjections.saveboxresource(...) end
44local usebox  = function(...) return nodeinjections.useboxresource(...) end
45local getbox  = function(...) return nodeinjections.getboxresourcebox(...) end
46local getwhd  = function(...) return codeinjections.getboxresourcedimensions(...) end
47
48tex.saveboxresource          = savebox
49tex.useboxresource           = usebox
50tex.getboxresourcebox        = getbox
51tex.getboxresourcedimensions = getwhd
52
53local boxresources = {
54    save          = savebox,
55    use           = usebox,
56    getbox        = getbox,
57    getdimensions = getwhd,
58}
59
60tex.boxresources = boxresources
61
62local lastindex = 0
63
64local function saveboxresource()
65    local immediate  = true
66    local kind       = scankeyword("type") and scaninteger() or 0
67    local attributes = scankeyword("attr") and scanstring() or nil
68    local resources  = scankeyword("resources") and scanstring() or nil
69    local margin     = scankeyword("margin") and scandimension() or 0 -- register
70    local boxnumber  = scaninteger()
71    --
72    lastindex = savebox(boxnumber,attributes,resources,immediate,kind,margin)
73    if trace then
74        report("\\saveboxresource: index %i",lastindex)
75    end
76end
77
78local function lastsavedboxresourceindex()
79    if trace then
80        report("\\lastsaveboxresourceindex: index %i",lastindex)
81    end
82 -- context("%i",lastindex)
83    return cardinal_value, lastindex or 0
84end
85
86local function useboxresource()
87    local width, height, depth = scanwhd()
88    local index = scaninteger()
89    local node  = usebox(index,width,height,depth)
90    if trace then
91        report("\\useboxresource: index %i",index)
92    end
93    context(node)
94end
95
96implement {
97    name    = "saveboxresource",
98    actions = saveboxresource,
99}
100implement {
101    name    = "lastsavedboxresourceindex",
102    public  = true,
103    usage   = "value",
104    actions = lastsavedboxresourceindex,
105}
106implement {
107    name    = "useboxresource",
108    actions = useboxresource,
109}
110
111-- used in pack
112
113do
114
115    local nuts      = nodes.nuts
116    local tonut     = nodes.tonut
117
118    local setwhd    = nuts.setwhd
119    local setlist   = nuts.setlist
120
121    local new_hlist = nuts.pool.hlist
122
123    function codeinjections.restoreboxresource(index)
124        local hbox = new_hlist()
125        local list, wd, ht, dp = usebox(index)
126        setlist(hbox,tonut(list))
127        setwhd(hbox,wd,ht,dp)
128        return hbox -- so we return a nut !
129    end
130
131    function codeinjections.registerboxresource(n,offset,delay,objnum)
132        local immediate = true
133        if delay == true or delay == 1 then
134            immediate = false
135        end
136        local r = savebox(n,nil,true,immediate,0,offset or 0,objnum)
137        return r
138    end
139
140end
141
142-- image resources
143
144local imageresources = { }
145local lastindex      = 0
146local lastpages      = 1
147
148local function saveimageresource()
149    local width, height, depth = scanwhd()
150    local page       = 1
151    local immediate  = true
152    local margin     = 0 -- or dimension
153    local attributes = scankeyword("attr") and scanstring() or nil
154    if scankeyword("named") then
155        scanstring() -- ignored
156    elseif scankeyword("page") then
157        page = scaninteger()
158    end
159    local userpassword    = scankeyword("userpassword") and scanstring() or nil
160    local ownerpassword   = scankeyword("ownerpassword") and scanstring() or nil
161    local visiblefilename = scankeyword("visiblefilename") and scanstring() or nil
162    local colorspace      = scankeyword("colorspace") and scaninteger() or nil
163    local pagebox         = scanword() or nil
164    local filename        = scanstring()
165-- pcall
166    context.getfiguredimensions( { filename }, {
167        [constants.userpassword]  = userpassword,
168        [constants.ownerpassword] = ownerpassword,
169        [constants.page]          = page or 1,
170        [constants.size]          = pagebox,
171    })
172    context.relax()
173    lastindex = lastindex + 1
174    lastpages = 1
175    imageresources[lastindex] = {
176        filename = filename,
177        page     = page or 1,
178        size     = pagebox,
179        width    = width,
180        height   = height,
181        depth    = depth,
182        attr     = attributes,
183     -- margin   = margin,
184     }
185end
186
187local function lastsavedimageresourceindex()
188--     context("%i",lastindex or 0)
189    return cardinal_value, lastindex or 0
190end
191
192local function lastsavedimageresourcepages()
193--     context("%i",lastpages or 0) -- todo
194    return cardinal_value, lastpages or 0
195end
196
197local function useimageresource()
198    local width, height, depth = scanwhd()
199    if scankeyword("keepopen") then
200        -- ignored
201    end
202    local index = scaninteger()
203    local l = imageresources[index]
204    if l then
205        if not (width or height or depth) then
206            width  = l.width
207            height = l.height
208            depth  = l.depth
209        end
210        -- pcall / we could use a dedicated call instead:
211        context.externalfigure( { l.filename }, {
212            [constants.userpassword]  = l.userpassword,
213            [constants.ownerpassword] = l.ownerpassword,
214            [constants.width]         = width and (width .. "sp") or nil,
215            [constants.height]        = height and (height .. "sp") or nil,
216            [constants.page]          = l.page or 1,
217            [constants.size]          = pagebox,
218        })
219        context.relax()
220    else
221        report("no valid image resource %a",index)
222    end
223end
224
225implement {
226    name    = "saveimageresource",
227    actions = saveimageresource,
228}
229
230implement {
231    name    = "lastsavedimageresourceindex",
232    public  = true,
233    usage   = "value",
234    actions = lastsavedimageresourceindex,
235}
236
237implement {
238    name    = "lastsavedimageresourcepages",
239    public  = true,
240    usage   = "value",
241    actions = lastsavedimageresourcepages,
242}
243
244implement {
245    name    = "useimageresource",
246    actions = useimageresource,
247}
248