diff options
Diffstat (limited to 'Master/texmf-dist/tex/context/base/lpdf-ren.lua')
-rw-r--r-- | Master/texmf-dist/tex/context/base/lpdf-ren.lua | 184 |
1 files changed, 119 insertions, 65 deletions
diff --git a/Master/texmf-dist/tex/context/base/lpdf-ren.lua b/Master/texmf-dist/tex/context/base/lpdf-ren.lua index e6bbd67fe2e..54c78845ed4 100644 --- a/Master/texmf-dist/tex/context/base/lpdf-ren.lua +++ b/Master/texmf-dist/tex/context/base/lpdf-ren.lua @@ -10,70 +10,97 @@ if not modules then modules = { } end modules ['lpdf-ren'] = { local tostring, tonumber, next = tostring, tonumber, next local format = string.format -local texsprint, ctxcatcodes = tex.sprint, tex.ctxcatcodes +local settings_to_array = utilities.parsers.settings_to_array -local nodeinjections = backends.pdf.nodeinjections -local codeinjections = backends.pdf.codeinjections -local registrations = backends.pdf.registrations +local backends, lpdf = backends, lpdf -jobreferences = jobreferences or { } ---~ jobreferences.runners = jobreferences.runners or { } ---~ jobreferences.specials = jobreferences.specials or { } ---~ jobreferences.handlers = jobreferences.handlers or { } -jobreferences.executers = jobreferences.executers or { } +local nodeinjections = backends.pdf.nodeinjections +local codeinjections = backends.pdf.codeinjections +local registrations = backends.pdf.registrations +local viewerlayers = attributes.viewerlayers ---~ local runners = jobreferences.runners ---~ local specials = jobreferences.specials ---~ local handlers = jobreferences.handlers -local executers = jobreferences.executers +local references = structures.references -local variables = interfaces.variables +references.executers = references.executers or { } +local executers = references.executers -local pdfconstant = lpdf.constant -local pdfdictionary = lpdf.dictionary -local pdfarray = lpdf.array -local pdfreference = lpdf.reference -local pdfflushobject = lpdf.flushobject +local variables = interfaces.variables -local pdf_ocg = pdfconstant("OCG") -local pdf_ocmd = pdfconstant("OCMD") -local pdf_off = pdfconstant("OFF") -local pdf_on = pdfconstant("ON") -local pdf_toggle = pdfconstant("Toggle") -local pdf_setocgstate = pdfconstant("SetOCGState") +local v_no = variables.no +local v_yes = variables.yes +local v_start = variables.start +local v_stop = variables.stop +local v_reset = variables.reset +local v_auto = variables.auto +local v_random = variables.random -local lpdf_usage = pdfdictionary { Print = pdfdictionary { PrintState = pdfconstant("OFF") } } +local pdfconstant = lpdf.constant +local pdfdictionary = lpdf.dictionary +local pdfarray = lpdf.array +local pdfreference = lpdf.reference +local pdfflushobject = lpdf.flushobject +local pdfreserveobject = lpdf.reserveobject + +local pdf_ocg = pdfconstant("OCG") +local pdf_ocmd = pdfconstant("OCMD") +local pdf_off = pdfconstant("OFF") +local pdf_on = pdfconstant("ON") +local pdf_toggle = pdfconstant("Toggle") +local pdf_setocgstate = pdfconstant("SetOCGState") + +local lpdf_usage = pdfdictionary { Print = pdfdictionary { PrintState = pdf_off } } + +-- We can have references to layers before they are places, for instance from +-- hide and vide actions. This is why we need to be able to force usage of layers +-- at several moments. local pdfln, pdfld = { }, { } local textlayers, hidelayers, videlayers = pdfarray(), pdfarray(), pdfarray() -local pagelayers = pdfdictionary() +local pagelayers, pagelayersreference, cache = nil, nil, { } -lpdf.layerreferences = pdfln +local specifications = { } +local initialized = { } -function backends.pdf.layerreference(name) - return pdfln[name] +function codeinjections.defineviewerlayer(specification) + if viewerlayers.supported and textlayers then + local tag = specification.tag + if not specifications[tag] then + specifications[tag] = specification + end + end end -function codeinjections.defineviewerlayer(specification) - if textlayers then +local function useviewerlayer(name) + local specification = specifications[name] + if not environment.initex and specification and not initialized[name] then + specifications[name] = nil -- or not + initialized [name] = true + if not pagelayers then + pagelayers = pdfdictionary() + pagelayersreference = pdfreserveobject() + end local tag = specification.tag -- todo: reserve - local n = pdfdictionary { + local nn = pdfreserveobject() + local nr = pdfreference(nn) + local nd = pdfdictionary { Type = pdf_ocg, Name = specification.title or "unknown", - Intent = ((specification.kind > 0) and pdf_design) or nil, -- disable layer hiding by user - Usage = ((specification.printable == variables.no) and lpdf_usage) or nil , -- printable or not + Intent = ((specification.editable ~= v_no) and pdf_design) or nil, -- disable layer hiding by user + Usage = ((specification.printable == v_no) and lpdf_usage) or nil, -- printable or not } - local nr = pdfreference(pdfflushobject(n)) + cache[#cache+1] = { nn, nd } pdfln[tag] = nr -- was n - local d = pdfdictionary { + local dn = pdfreserveobject() + local dr = pdfreference(dn) + local dd = pdfdictionary { Type = pdf_ocmd, OCGs = pdfarray { nr }, } - local dr = pdfreference(pdfflushobject(d)) + cache[#cache+1] = { dn, dd } pdfld[tag] = dr textlayers[#textlayers+1] = nr - if specification.visible == variables.start then + if specification.visible == v_start then videlayers[#videlayers+1] = nr else hidelayers[#hidelayers+1] = nr @@ -82,36 +109,61 @@ function codeinjections.defineviewerlayer(specification) end end +codeinjections.useviewerlayer = useviewerlayer + +local function layerreference(name) + local r = pdfln[name] + if r then + return r + else + useviewerlayer(name) + return pdfln[name] + end +end + +lpdf.layerreference = layerreference -- also triggered when a hide or vide happens + local function flushtextlayers() - if textlayers and #textlayers > 0 then - local d = pdfdictionary { - OCGs = textlayers, - D = pdfdictionary { - Order = textlayers, - ON = videlayers, - OFF = hidelayers, - }, - } - lpdf.addtocatalog("OCProperties",d) - textlayers = nil + if viewerlayers.supported then + if pagelayers then + pdfflushobject(pagelayersreference,pagelayers) + end + for i=1,#cache do + local ci = cache[i] + pdfflushobject(ci[1],ci[2]) + end + if textlayers and #textlayers > 0 then -- we can group them if needed, like: layout + local d = pdfdictionary { + OCGs = textlayers, + D = pdfdictionary { + Name = "Document", + Order = (viewerlayers.hasorder and textlayers) or nil, + ON = videlayers, + OFF = hidelayers, + BaseState = pdf_on, + }, + } + lpdf.addtocatalog("OCProperties",d) + textlayers = nil + end end end -local function flushpagelayers() - if next(pagelayers) then - lpdf.addtopageresources("Properties",pagelayers) +local function flushpagelayers() -- we can share these + if pagelayers then + lpdf.addtopageresources("Properties",pdfreference(pagelayersreference)) -- we could cache this end end -lpdf.registerpagefinalizer (flushpagelayers) -lpdf.registerdocumentfinalizer(flushtextlayers) +lpdf.registerpagefinalizer (flushpagelayers,"layers") +lpdf.registerdocumentfinalizer(flushtextlayers,"layers") local function setlayer(what,arguments) -- maybe just a gmatch of even better, earlier in lpeg - arguments = (type(arguments) == "table" and arguments) or aux.settings_to_array(arguments) + arguments = (type(arguments) == "table" and arguments) or settings_to_array(arguments) local state = pdfarray { what } for i=1,#arguments do - local p = pdfln[arguments[i]] + local p = layerreference(arguments[i]) if p then state[#state+1] = p end @@ -122,9 +174,9 @@ local function setlayer(what,arguments) } end -function executers.hidelayer (arguments) setlayer(pdf_off, arguments) end -function executers.videlayer (arguments) setlayer(pdf_on, arguments) end -function executers.togglelayer(arguments) setlayer(pdf_toggle,arguments) end +function executers.hidelayer (arguments) return setlayer(pdf_off, arguments) end +function executers.videlayer (arguments) return setlayer(pdf_on, arguments) end +function executers.togglelayer(arguments) return setlayer(pdf_toggle,arguments) end -- transitions @@ -173,24 +225,26 @@ local last = 0 function codeinjections.setpagetransition(specification) local n, delay = specification.n, specification.delay - if n == variables.auto then + if not n or n == "" then + return -- let's forget about it + elseif n == v_auto then if last >= #pagetransitions then last = 0 end n = last + 1 - elseif n == variables.stop then + elseif n == v_stop then return - elseif n == variables.reset then + elseif n == v_reset then last = 0 return - elseif n == variables.random then + elseif n == v_random then n = math.random(1,#pagetransitions) else n = tonumber(n) end local t = n and pagetransitions[n] or pagetransitions[1] if not t then - t = aux.settings_to_array(n) + t = settings_to_array(n) end if t and #t > 0 then local d = pdfdictionary() |