diff options
author | Marius <mariausol@gmail.com> | 2013-05-20 03:20:28 +0300 |
---|---|---|
committer | Marius <mariausol@gmail.com> | 2013-05-20 03:20:28 +0300 |
commit | 5fc5cfb5014ddcc2942e13a559f4082fb66aa6e7 (patch) | |
tree | 53f81e99fac8c80ddd2fb70e233a7e5d5735722f /tex/context/base/lpdf-ren.lua | |
parent | 13ec4b540e0d46c97fd7b089e0b7413da81e0a9f (diff) | |
download | context-5fc5cfb5014ddcc2942e13a559f4082fb66aa6e7.tar.gz |
beta 2013.05.20 02:00
Diffstat (limited to 'tex/context/base/lpdf-ren.lua')
-rw-r--r-- | tex/context/base/lpdf-ren.lua | 698 |
1 files changed, 349 insertions, 349 deletions
diff --git a/tex/context/base/lpdf-ren.lua b/tex/context/base/lpdf-ren.lua index 19582817d..6af65f9de 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 |