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