back-pdp.lua /size: 8400 b    last modification: 2021-10-28 13:50
1if not modules then modules = { } end modules ['back-pdp'] = {
2    version   = 1.001,
3    comment   = "companion to lpdf-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-- This is temporary ... awaiting a better test .. basically we can
10-- always use this: pdf primitives.
11
12local context           = context
13local lpdf              = lpdf
14
15local lpdfreserveobject = lpdf.reserveobject
16local lpdfcompresslevel = lpdf.compresslevel
17local lpdfobj           = lpdf.obj
18local lpdfpagereference = lpdf.pagereference
19local lpdfxformname     = lpdf.xformname
20
21local tokenscanners     = tokens.scanners
22local scanword          = tokenscanners.word
23local scankeyword       = tokenscanners.keyword
24local scanstring        = tokenscanners.string
25local scaninteger       = tokenscanners.integer
26local scanwhd           = tokenscanners.whd
27
28local trace             = false  trackers.register("backend", function(v) trace = v end)
29local report            = logs.reporter("backend")
30
31local nodepool          = nodes.pool
32local newliteral        = nodepool.literal
33local newsave           = nodepool.save
34local newrestore        = nodepool.restore
35local newsetmatrix      = nodepool.setmatrix
36
37local implement         = interfaces.implement
38local constants         = interfaces.constants
39local variables         = interfaces.variables
40
41-- literals
42
43local function pdfliteral()
44    context(newliteral(scanword() or "origin",scanstring()))
45end
46
47-- objects
48
49local lastobjnum = 0
50
51local function pdfobj()
52    if scankeyword("reserveobjnum") then
53        lastobjnum = lpdfreserveobject()
54        if trace then
55            report("\\pdfobj reserveobjnum: object %i",lastobjnum)
56        end
57    else
58        local immediate    = true
59        local objnum       = scankeyword("useobjnum") and scaninteger() or lpdfreserveobject()
60        local uncompress   = scankeyword("uncompressed") or lpdfcompresslevel() == 0
61        local streamobject = scankeyword("stream")
62        local attributes   = scankeyword("attr") and scanstring() or nil
63        local fileobject   = scankeyword("file")
64        local content      = scanstring()
65        local object = streamobject and {
66            type          = "stream",
67            objnum        = objnum,
68            immediate     = immediate,
69            attr          = attributes,
70            compresslevel = uncompress and 0 or nil,
71        } or {
72            type          = "raw",
73            objnum        = objnum,
74            immediate     = immediate,
75        }
76        if fileobject then
77            object.file = content
78         -- object.filename = content
79        else
80            object.string = content
81        end
82        lpdfobj(object)
83        lastobjnum = objnum
84        if trace then
85            report("\\pdfobj: object %i",lastobjnum)
86        end
87    end
88end
89
90local function pdflastobj()
91    context("%i",lastobjnum)
92    if trace then
93        report("\\lastobj: object %i",lastobjnum)
94    end
95end
96
97local function pdfrefobj()
98    local objnum = scaninteger()
99    if trace then
100        report("\\refobj: object %i (todo)",objnum)
101    end
102end
103
104-- annotations
105
106local lastobjnum = 0
107
108local function pdfannot()
109    if scankeyword("reserveobjnum") then
110        lastobjnum = lpdfreserveobject()
111        if trace then
112            report("\\pdfannot reserveobjnum: object %i",lastobjnum)
113        end
114    else
115        local width  = false
116        local height = false
117        local depth  = false
118        local data   = false
119        local object = false
120        local attr   = false
121        --
122        if scankeyword("useobjnum") then
123            object = scancount()
124            report("\\pdfannot useobjectnum is not (yet) supported")
125        end
126        local width, height, depth = scanwhd()
127        if scankeyword("attr") then
128            attr = scanstring()
129        end
130        data = scanstring()
131        context(backends.nodeinjections.annotation(width or 0,height or 0,depth or 0,data or ""))
132    end
133end
134
135local function pdfdest()
136    local name   = false
137    local zoom   = false
138    local view   = false
139    local width  = false
140    local height = false
141    local depth  = false
142    if scankeyword("num") then
143        report("\\pdfdest num is not (yet) supported")
144    elseif scankeyword("name") then
145        name = scanstring()
146    end
147    if scankeyword("xyz") then
148        view = "xyz"
149        if scankeyword("zoom") then
150            report("\\pdfdest zoom is ignored")
151            zoom = scancount() -- will be divided by 1000 in the backend
152        end
153    elseif scankeyword("fitbh") then
154        view = "fitbh"
155    elseif scankeyword("fitbv") then
156        view = "fitbv"
157    elseif scankeyword("fitb") then
158        view = "fitb"
159    elseif scankeyword("fith") then
160        view = "fith"
161    elseif scankeyword("fitv") then
162        view = "fitv"
163    elseif scankeyword("fitr") then
164        view = "fitr"
165        width, height, depth = scanwhd()
166    elseif scankeyword("fit") then
167        view = "fit"
168    end
169    context(backends.nodeinjections.destination(width or 0,height or 0,depth or 0,{ name or "" },view or "fit"))
170end
171
172-- management
173
174local function pdfsave()
175    context(newsave())
176end
177
178local function pdfrestore()
179    context(newrestore())
180end
181
182local function pdfsetmatrix()
183    context(newsetmatrix(scanstring()))
184end
185
186-- extras
187
188local function pdfpageref()
189    context(lpdfpagereference())
190end
191
192local function pdfxformname()
193    context(lpdfxformname())
194end
195
196-- extensions: literal dest annot save restore setmatrix obj refobj colorstack
197-- startlink endlink startthread endthread thread outline glyphtounicode fontattr
198-- mapfile mapline includechars catalog info names trailer
199
200local extensions = {
201    literal   = pdfliteral,
202    obj       = pdfobj,
203    refobj    = pdfrefobj,
204    dest      = pdfdest,
205    annot     = pdfannot,
206    save      = pdfsave,
207    restore   = pdfrestore,
208    setmatrix = pdfsetmatrix,
209}
210
211local function pdfextension()
212    local w = scanword()
213    if w then
214        local e = extensions[w]
215        if e then
216            e()
217        else
218            report("\\pdfextension: unsupported %a",w)
219        end
220    end
221end
222
223-- feedbacks: colorstackinit creationdate fontname fontobjnum fontsize lastannot
224-- lastlink lastobj pageref retval revision version xformname
225
226local feedbacks = {
227    lastobj    = pdflastobj,
228    pageref    = pdfpageref,
229    xformname  = pdfxformname,
230}
231
232local function pdffeedback()
233    local w = scanword()
234    if w then
235        local f = feedbacks[w]
236        if f then
237            f()
238        else
239            report("\\pdffeedback: unsupported %a",w)
240        end
241    end
242end
243
244-- variables: (integers:) compresslevel decimaldigits gamma gentounicode
245-- ignoreunknownimages imageaddfilename imageapplygamma imagegamma imagehicolor
246-- imageresolution inclusioncopyfonts inclusionerrorlevel majorversion minorversion
247-- objcompresslevel omitcharset omitcidset pagebox pkfixeddpi pkresolution
248-- recompress suppressoptionalinfo uniqueresname (dimensions:) destmargin horigin
249-- linkmargin threadmargin vorigin xformmargin (tokenlists:) pageattr pageresources
250-- pagesattr pkmode trailerid xformattr xformresources
251
252local variables = {
253    minorversion = function() context(lpdf.minorversion()) end,
254    majorversion = function() context(lpdf.majorversion()) end,
255}
256
257local function pdfvariable()
258    local w = scanword()
259    if w then
260        local f = variables[w]
261        if f then
262            f()
263        else
264            report("\\pdfvariable: unsupported %a",w)
265        end
266    else
267        print("missing variable")
268    end
269end
270
271-- kept:
272
273implement { name = "pdfextension", actions = pdfextension }
274implement { name = "pdffeedback",  actions = pdffeedback }
275implement { name = "pdfvariable",  actions = pdfvariable }
276
277-- for the moment (tikz)
278
279implement { name = "pdfliteral",    actions = pdfliteral }
280implement { name = "pdfobj",        actions = pdfobj }
281implement { name = "pdflastobj",    actions = pdflastobj }
282implement { name = "pdfrefobj",     actions = pdfrefobj }
283--------- { name = "pdfannot",      actions = pdfannot }
284--------- { name = "pdfdest",       actions = pdfdest }
285--------- { name = "pdfsave",       actions = pdfsave }
286--------- { name = "pdfrestore",    actions = pdfrestore }
287--------- { name = "pdfsetmatrix",  actions = pdfsetmatrix }
288