summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/context/base/lpdf-ren.lua
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/tex/context/base/lpdf-ren.lua')
-rw-r--r--Master/texmf-dist/tex/context/base/lpdf-ren.lua184
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()