summaryrefslogtreecommitdiff
path: root/tex/context/base/lpdf-ren.lua
diff options
context:
space:
mode:
Diffstat (limited to 'tex/context/base/lpdf-ren.lua')
-rw-r--r--tex/context/base/lpdf-ren.lua698
1 files changed, 349 insertions, 349 deletions
diff --git a/tex/context/base/lpdf-ren.lua b/tex/context/base/lpdf-ren.lua
index 6af65f9de..19582817d 100644
--- a/tex/context/base/lpdf-ren.lua
+++ b/tex/context/base/lpdf-ren.lua
@@ -1,349 +1,349 @@
-if not modules then modules = { } end modules ['lpdf-ren'] = {
- version = 1.001,
- comment = "companion to lpdf-ini.mkiv",
- author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright = "PRAGMA ADE / ConTeXt Development Team",
- license = "see context related readme files"
-}
-
--- rendering
-
-local tostring, tonumber, next = tostring, tonumber, next
-local format, rep = string.format, string.rep
-local concat = table.concat
-local settings_to_array = utilities.parsers.settings_to_array
-
-local backends, lpdf, nodes, node = backends, lpdf, nodes, node
-
-local nodeinjections = backends.pdf.nodeinjections
-local codeinjections = backends.pdf.codeinjections
-local registrations = backends.pdf.registrations
-local viewerlayers = attributes.viewerlayers
-
-local references = structures.references
-
-references.executers = references.executers or { }
-local executers = references.executers
-
-local variables = interfaces.variables
-
-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 pdfconstant = lpdf.constant
-local pdfdictionary = lpdf.dictionary
-local pdfarray = lpdf.array
-local pdfreference = lpdf.reference
-local pdfflushobject = lpdf.flushobject
-local pdfreserveobject = lpdf.reserveobject
-
-local nodepool = nodes.pool
-local register = nodepool.register
-local pdfliteral = nodepool.pdfliteral
-
-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 copy_node = node.copy
-
-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.
-
--- management
-
-local pdfln, pdfld = { }, { }
-local textlayers, hidelayers, videlayers = pdfarray(), pdfarray(), pdfarray()
-local pagelayers, pagelayersreference, cache = nil, nil, { }
-local alphabetic = { }
-
-local specifications = { }
-local initialized = { }
-
-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
-
-local function useviewerlayer(name) -- move up so that we can use it as local
- if not environment.initex and not initialized[name] then
- local specification = specifications[name]
- if specification 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 nn = pdfreserveobject()
- local nr = pdfreference(nn)
- local nd = pdfdictionary {
- Type = pdf_ocg,
- Name = specification.title or "unknown",
- 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
- }
- cache[#cache+1] = { nn, nd }
- pdfln[tag] = nr -- was n
- local dn = pdfreserveobject()
- local dr = pdfreference(dn)
- local dd = pdfdictionary {
- Type = pdf_ocmd,
- OCGs = pdfarray { nr },
- }
- cache[#cache+1] = { dn, dd }
- pdfld[tag] = dr
- textlayers[#textlayers+1] = nr
- alphabetic[tag] = nr
- if specification.visible == v_start then
- videlayers[#videlayers+1] = nr
- else
- hidelayers[#hidelayers+1] = nr
- end
- pagelayers[tag] = dr -- check
- else
- -- todo: message
- end
- 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 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 sortedlayers = { }
- for k, v in table.sortedhash(alphabetic) do
- sortedlayers[#sortedlayers+1] = v -- maybe do a proper numeric sort as well
- end
- local d = pdfdictionary {
- OCGs = textlayers,
- D = pdfdictionary {
- Name = "Document",
- -- Order = (viewerlayers.hasorder and textlayers) or nil,
- Order = (viewerlayers.hasorder and sortedlayers) or nil,
- ON = videlayers,
- OFF = hidelayers,
- BaseState = pdf_on,
- },
- }
- lpdf.addtocatalog("OCProperties",d)
- textlayers = nil
- end
- end
-end
-
-local function flushpagelayers() -- we can share these
- if pagelayers then
- lpdf.addtopageresources("Properties",pdfreference(pagelayersreference)) -- we could cache this
- end
-end
-
-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 settings_to_array(arguments)
- local state = pdfarray { what }
- for i=1,#arguments do
- local p = layerreference(arguments[i])
- if p then
- state[#state+1] = p
- end
- end
- return pdfdictionary {
- S = pdf_setocgstate,
- State = state,
- }
-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
-
--- injection
-
-function codeinjections.startlayer(name) -- used in mp
- if not name then
- name = "unknown"
- end
- useviewerlayer(name)
- return format("/OC /%s BDC",name)
-end
-
-function codeinjections.stoplayer(name) -- used in mp
- return "EMC"
-end
-
-local cache = { }
-
-function nodeinjections.startlayer(name)
- local c = cache[name]
- if not c then
- useviewerlayer(name)
- c = register(pdfliteral(format("/OC /%s BDC",name)))
- cache[name] = c
- end
- return copy_node(c)
-end
-
-local stop = register(pdfliteral("EMC"))
-
-function nodeinjections.stoplayer()
- return copy_node(stop)
-end
-
--- experimental stacker code (slow, can be optimized): !!!! TEST CODE !!!!
-
-local values = viewerlayers.values
-local startlayer = codeinjections.startlayer
-local stoplayer = codeinjections.stoplayer
-
-function nodeinjections.startstackedlayer(s,t,first,last)
- local r = { }
- for i=first,last do
- r[#r+1] = startlayer(values[t[i]])
- end
- r = concat(r," ")
- return pdfliteral(r)
-end
-
-function nodeinjections.stopstackedlayer(s,t,first,last)
- local r = { }
- for i=last,first,-1 do
- r[#r+1] = stoplayer()
- end
- r = concat(r," ")
- return pdfliteral(r)
-end
-
-function nodeinjections.changestackedlayer(s,t1,first1,last1,t2,first2,last2)
- local r = { }
- for i=last1,first1,-1 do
- r[#r+1] = stoplayer()
- end
- for i=first2,last2 do
- r[#r+1] = startlayer(values[t2[i]])
- end
- r = concat(r," ")
- return pdfliteral(r)
-end
-
--- transitions
-
-local pagetransitions = {
- {"split","in","vertical"}, {"split","in","horizontal"},
- {"split","out","vertical"}, {"split","out","horizontal"},
- {"blinds","horizontal"}, {"blinds","vertical"},
- {"box","in"}, {"box","out"},
- {"wipe","east"}, {"wipe","west"}, {"wipe","north"}, {"wipe","south"},
- {"dissolve"},
- {"glitter","east"}, {"glitter","south"},
- {"fly","in","east"}, {"fly","in","west"}, {"fly","in","north"}, {"fly","in","south"},
- {"fly","out","east"}, {"fly","out","west"}, {"fly","out","north"}, {"fly","out","south"},
- {"push","east"}, {"push","west"}, {"push","north"}, {"push","south"},
- {"cover","east"}, {"cover","west"}, {"cover","north"}, {"cover","south"},
- {"uncover","east"}, {"uncover","west"}, {"uncover","north"}, {"uncover","south"},
- {"fade"},
-}
-
-local mapping = {
- split = { "S" , pdfconstant("Split") },
- blinds = { "S" , pdfconstant("Blinds") },
- box = { "S" , pdfconstant("Box") },
- wipe = { "S" , pdfconstant("Wipe") },
- dissolve = { "S" , pdfconstant("Dissolve") },
- glitter = { "S" , pdfconstant("Glitter") },
- replace = { "S" , pdfconstant("R") },
- fly = { "S" , pdfconstant("Fly") },
- push = { "S" , pdfconstant("Push") },
- cover = { "S" , pdfconstant("Cover") },
- uncover = { "S" , pdfconstant("Uncover") },
- fade = { "S" , pdfconstant("Fade") },
- horizontal = { "Dm" , pdfconstant("H") },
- vertical = { "Dm" , pdfconstant("V") },
- ["in"] = { "M" , pdfconstant("I") },
- out = { "M" , pdfconstant("O") },
- east = { "Di" , 0 },
- north = { "Di" , 90 },
- west = { "Di" , 180 },
- south = { "Di" , 270 },
-}
-
-local last = 0
-
--- n: number, "stop", "reset", "random", "a,b,c" delay: number, "none"
-
-function codeinjections.setpagetransition(specification)
- local n, delay = specification.n, specification.delay
- 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 == v_stop then
- return
- elseif n == v_reset then
- last = 0
- return
- 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 = settings_to_array(n)
- end
- if t and #t > 0 then
- local d = pdfdictionary()
- for i=1,#t do
- local m = mapping[t[i]]
- d[m[1]] = m[2]
- end
- delay = tonumber(delay)
- if delay and delay > 0 then
- lpdf.addtopageattributes("Dur",delay)
- end
- lpdf.addtopageattributes("Trans",d)
- end
-end
+if not modules then modules = { } end modules ['lpdf-ren'] = {
+ version = 1.001,
+ comment = "companion to lpdf-ini.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- rendering
+
+local tostring, tonumber, next = tostring, tonumber, next
+local format, rep = string.format, string.rep
+local concat = table.concat
+local settings_to_array = utilities.parsers.settings_to_array
+
+local backends, lpdf, nodes, node = backends, lpdf, nodes, node
+
+local nodeinjections = backends.pdf.nodeinjections
+local codeinjections = backends.pdf.codeinjections
+local registrations = backends.pdf.registrations
+local viewerlayers = attributes.viewerlayers
+
+local references = structures.references
+
+references.executers = references.executers or { }
+local executers = references.executers
+
+local variables = interfaces.variables
+
+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 pdfconstant = lpdf.constant
+local pdfdictionary = lpdf.dictionary
+local pdfarray = lpdf.array
+local pdfreference = lpdf.reference
+local pdfflushobject = lpdf.flushobject
+local pdfreserveobject = lpdf.reserveobject
+
+local nodepool = nodes.pool
+local register = nodepool.register
+local pdfliteral = nodepool.pdfliteral
+
+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 copy_node = node.copy
+
+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.
+
+-- management
+
+local pdfln, pdfld = { }, { }
+local textlayers, hidelayers, videlayers = pdfarray(), pdfarray(), pdfarray()
+local pagelayers, pagelayersreference, cache = nil, nil, { }
+local alphabetic = { }
+
+local specifications = { }
+local initialized = { }
+
+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
+
+local function useviewerlayer(name) -- move up so that we can use it as local
+ if not environment.initex and not initialized[name] then
+ local specification = specifications[name]
+ if specification 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 nn = pdfreserveobject()
+ local nr = pdfreference(nn)
+ local nd = pdfdictionary {
+ Type = pdf_ocg,
+ Name = specification.title or "unknown",
+ 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
+ }
+ cache[#cache+1] = { nn, nd }
+ pdfln[tag] = nr -- was n
+ local dn = pdfreserveobject()
+ local dr = pdfreference(dn)
+ local dd = pdfdictionary {
+ Type = pdf_ocmd,
+ OCGs = pdfarray { nr },
+ }
+ cache[#cache+1] = { dn, dd }
+ pdfld[tag] = dr
+ textlayers[#textlayers+1] = nr
+ alphabetic[tag] = nr
+ if specification.visible == v_start then
+ videlayers[#videlayers+1] = nr
+ else
+ hidelayers[#hidelayers+1] = nr
+ end
+ pagelayers[tag] = dr -- check
+ else
+ -- todo: message
+ end
+ 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 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 sortedlayers = { }
+ for k, v in table.sortedhash(alphabetic) do
+ sortedlayers[#sortedlayers+1] = v -- maybe do a proper numeric sort as well
+ end
+ local d = pdfdictionary {
+ OCGs = textlayers,
+ D = pdfdictionary {
+ Name = "Document",
+ -- Order = (viewerlayers.hasorder and textlayers) or nil,
+ Order = (viewerlayers.hasorder and sortedlayers) or nil,
+ ON = videlayers,
+ OFF = hidelayers,
+ BaseState = pdf_on,
+ },
+ }
+ lpdf.addtocatalog("OCProperties",d)
+ textlayers = nil
+ end
+ end
+end
+
+local function flushpagelayers() -- we can share these
+ if pagelayers then
+ lpdf.addtopageresources("Properties",pdfreference(pagelayersreference)) -- we could cache this
+ end
+end
+
+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 settings_to_array(arguments)
+ local state = pdfarray { what }
+ for i=1,#arguments do
+ local p = layerreference(arguments[i])
+ if p then
+ state[#state+1] = p
+ end
+ end
+ return pdfdictionary {
+ S = pdf_setocgstate,
+ State = state,
+ }
+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
+
+-- injection
+
+function codeinjections.startlayer(name) -- used in mp
+ if not name then
+ name = "unknown"
+ end
+ useviewerlayer(name)
+ return format("/OC /%s BDC",name)
+end
+
+function codeinjections.stoplayer(name) -- used in mp
+ return "EMC"
+end
+
+local cache = { }
+
+function nodeinjections.startlayer(name)
+ local c = cache[name]
+ if not c then
+ useviewerlayer(name)
+ c = register(pdfliteral(format("/OC /%s BDC",name)))
+ cache[name] = c
+ end
+ return copy_node(c)
+end
+
+local stop = register(pdfliteral("EMC"))
+
+function nodeinjections.stoplayer()
+ return copy_node(stop)
+end
+
+-- experimental stacker code (slow, can be optimized): !!!! TEST CODE !!!!
+
+local values = viewerlayers.values
+local startlayer = codeinjections.startlayer
+local stoplayer = codeinjections.stoplayer
+
+function nodeinjections.startstackedlayer(s,t,first,last)
+ local r = { }
+ for i=first,last do
+ r[#r+1] = startlayer(values[t[i]])
+ end
+ r = concat(r," ")
+ return pdfliteral(r)
+end
+
+function nodeinjections.stopstackedlayer(s,t,first,last)
+ local r = { }
+ for i=last,first,-1 do
+ r[#r+1] = stoplayer()
+ end
+ r = concat(r," ")
+ return pdfliteral(r)
+end
+
+function nodeinjections.changestackedlayer(s,t1,first1,last1,t2,first2,last2)
+ local r = { }
+ for i=last1,first1,-1 do
+ r[#r+1] = stoplayer()
+ end
+ for i=first2,last2 do
+ r[#r+1] = startlayer(values[t2[i]])
+ end
+ r = concat(r," ")
+ return pdfliteral(r)
+end
+
+-- transitions
+
+local pagetransitions = {
+ {"split","in","vertical"}, {"split","in","horizontal"},
+ {"split","out","vertical"}, {"split","out","horizontal"},
+ {"blinds","horizontal"}, {"blinds","vertical"},
+ {"box","in"}, {"box","out"},
+ {"wipe","east"}, {"wipe","west"}, {"wipe","north"}, {"wipe","south"},
+ {"dissolve"},
+ {"glitter","east"}, {"glitter","south"},
+ {"fly","in","east"}, {"fly","in","west"}, {"fly","in","north"}, {"fly","in","south"},
+ {"fly","out","east"}, {"fly","out","west"}, {"fly","out","north"}, {"fly","out","south"},
+ {"push","east"}, {"push","west"}, {"push","north"}, {"push","south"},
+ {"cover","east"}, {"cover","west"}, {"cover","north"}, {"cover","south"},
+ {"uncover","east"}, {"uncover","west"}, {"uncover","north"}, {"uncover","south"},
+ {"fade"},
+}
+
+local mapping = {
+ split = { "S" , pdfconstant("Split") },
+ blinds = { "S" , pdfconstant("Blinds") },
+ box = { "S" , pdfconstant("Box") },
+ wipe = { "S" , pdfconstant("Wipe") },
+ dissolve = { "S" , pdfconstant("Dissolve") },
+ glitter = { "S" , pdfconstant("Glitter") },
+ replace = { "S" , pdfconstant("R") },
+ fly = { "S" , pdfconstant("Fly") },
+ push = { "S" , pdfconstant("Push") },
+ cover = { "S" , pdfconstant("Cover") },
+ uncover = { "S" , pdfconstant("Uncover") },
+ fade = { "S" , pdfconstant("Fade") },
+ horizontal = { "Dm" , pdfconstant("H") },
+ vertical = { "Dm" , pdfconstant("V") },
+ ["in"] = { "M" , pdfconstant("I") },
+ out = { "M" , pdfconstant("O") },
+ east = { "Di" , 0 },
+ north = { "Di" , 90 },
+ west = { "Di" , 180 },
+ south = { "Di" , 270 },
+}
+
+local last = 0
+
+-- n: number, "stop", "reset", "random", "a,b,c" delay: number, "none"
+
+function codeinjections.setpagetransition(specification)
+ local n, delay = specification.n, specification.delay
+ 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 == v_stop then
+ return
+ elseif n == v_reset then
+ last = 0
+ return
+ 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 = settings_to_array(n)
+ end
+ if t and #t > 0 then
+ local d = pdfdictionary()
+ for i=1,#t do
+ local m = mapping[t[i]]
+ d[m[1]] = m[2]
+ end
+ delay = tonumber(delay)
+ if delay and delay > 0 then
+ lpdf.addtopageattributes("Dur",delay)
+ end
+ lpdf.addtopageattributes("Trans",d)
+ end
+end