summaryrefslogtreecommitdiff
path: root/tex/context/base/lpdf-wid.lua
diff options
context:
space:
mode:
Diffstat (limited to 'tex/context/base/lpdf-wid.lua')
-rw-r--r--tex/context/base/lpdf-wid.lua681
1 files changed, 0 insertions, 681 deletions
diff --git a/tex/context/base/lpdf-wid.lua b/tex/context/base/lpdf-wid.lua
deleted file mode 100644
index 22971c2b7..000000000
--- a/tex/context/base/lpdf-wid.lua
+++ /dev/null
@@ -1,681 +0,0 @@
-if not modules then modules = { } end modules ['lpdf-wid'] = {
- 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"
-}
-
-local gmatch, gsub, find, lower, format = string.gmatch, string.gsub, string.find, string.lower, string.format
-local stripstring = string.strip
-local settings_to_array = utilities.parsers.settings_to_array
-local settings_to_hash = utilities.parsers.settings_to_hash
-
-local report_media = logs.reporter("backend","media")
-local report_attachment = logs.reporter("backend","attachment")
-
-local backends = backends
-local lpdf = lpdf
-local nodes = nodes
-local context = context
-
-local texgetcount = tex.getcount
-
-local nodeinjections = backends.pdf.nodeinjections
-local codeinjections = backends.pdf.codeinjections
-local registrations = backends.pdf.registrations
-
-local executers = structures.references.executers
-local variables = interfaces.variables
-
-local v_hidden = variables.hidden
-local v_normal = variables.normal
-local v_auto = variables.auto
-local v_embed = variables.embed
-local v_unknown = variables.unknown
-local v_max = variables.max
-
-local pdfconstant = lpdf.constant
-local pdfdictionary = lpdf.dictionary
-local pdfarray = lpdf.array
-local pdfreference = lpdf.reference
-local pdfunicode = lpdf.unicode
-local pdfstring = lpdf.string
-local pdfboolean = lpdf.boolean
-local pdfcolorspec = lpdf.colorspec
-local pdfflushobject = lpdf.flushobject
-local pdfflushstreamobject = lpdf.flushstreamobject
-local pdfflushstreamfileobject = lpdf.flushstreamfileobject
-local pdfreserveobject = lpdf.reserveobject
-local pdfpagereference = lpdf.pagereference
-local pdfshareobjectreference = lpdf.shareobjectreference
-local pdfaction = lpdf.action
-local pdfborder = lpdf.border
-
-local pdftransparencyvalue = lpdf.transparencyvalue
-local pdfcolorvalues = lpdf.colorvalues
-
-local hpack_node = node.hpack
-local write_node = node.write -- test context(...) instead
-
--- symbols
-
-local presets = { } -- xforms
-
-local function registersymbol(name,n)
- presets[name] = pdfreference(n)
-end
-
-local function registeredsymbol(name)
- return presets[name]
-end
-
-local function presetsymbol(symbol)
- if not presets[symbol] then
- context.predefinesymbol { symbol }
- end
-end
-
-local function presetsymbollist(list)
- if list then
- for symbol in gmatch(list,"[^, ]+") do
- presetsymbol(symbol)
- end
- end
-end
-
-codeinjections.registersymbol = registersymbol
-codeinjections.registeredsymbol = registeredsymbol
-codeinjections.presetsymbol = presetsymbol
-codeinjections.presetsymbollist = presetsymbollist
-
--- comments
-
--- local symbols = {
--- Addition = pdfconstant("NewParagraph"),
--- Attachment = pdfconstant("Attachment"),
--- Balloon = pdfconstant("Comment"),
--- Check = pdfconstant("Check Mark"),
--- CheckMark = pdfconstant("Check Mark"),
--- Circle = pdfconstant("Circle"),
--- Cross = pdfconstant("Cross"),
--- CrossHairs = pdfconstant("Cross Hairs"),
--- Graph = pdfconstant("Graph"),
--- InsertText = pdfconstant("Insert Text"),
--- New = pdfconstant("Insert"),
--- Paperclip = pdfconstant("Paperclip"),
--- RightArrow = pdfconstant("Right Arrow"),
--- RightPointer = pdfconstant("Right Pointer"),
--- Star = pdfconstant("Star"),
--- Tag = pdfconstant("Tag"),
--- Text = pdfconstant("Note"),
--- TextNote = pdfconstant("Text Note"),
--- UpArrow = pdfconstant("Up Arrow"),
--- UpLeftArrow = pdfconstant("Up-Left Arrow"),
--- }
-
-local attachment_symbols = {
- Graph = pdfconstant("Graph"),
- Paperclip = pdfconstant("Paperclip"),
- Pushpin = pdfconstant("PushPin"),
-}
-
-attachment_symbols.PushPin = attachment_symbols.Pushpin
-attachment_symbols.Default = attachment_symbols.Pushpin
-
-local comment_symbols = {
- Comment = pdfconstant("Comment"),
- Help = pdfconstant("Help"),
- Insert = pdfconstant("Insert"),
- Key = pdfconstant("Key"),
- Newparagraph = pdfconstant("NewParagraph"),
- Note = pdfconstant("Note"),
- Paragraph = pdfconstant("Paragraph"),
-}
-
-comment_symbols.NewParagraph = Newparagraph
-comment_symbols.Default = Note
-
-local function analyzesymbol(symbol,collection)
- if not symbol or symbol == "" then
- return collection.Default, nil
- elseif collection[symbol] then
- return collection[symbol], nil
- else
- local setn, setr, setd
- local set = settings_to_array(symbol)
- if #set == 1 then
- setn, setr, setd = set[1], set[1], set[1]
- elseif #set == 2 then
- setn, setr, setd = set[1], set[1], set[2]
- else
- setn, setr, setd = set[1], set[2], set[3]
- end
- local appearance = pdfdictionary {
- N = setn and registeredsymbol(setn),
- R = setr and registeredsymbol(setr),
- D = setd and registeredsymbol(setd),
- }
- local appearanceref = pdfshareobjectreference(appearance)
- return nil, appearanceref
- end
-end
-
-local function analyzelayer(layer)
- -- todo: (specification.layer ~= "" and pdfreference(specification.layer)) or nil, -- todo: ref to layer
-end
-
-local function analyzecolor(colorvalue,colormodel)
- local cvalue = colorvalue and tonumber(colorvalue)
- local cmodel = colormodel and tonumber(colormodel) or 3
- return cvalue and pdfarray { pdfcolorvalues(cmodel,cvalue) } or nil
-end
-
-local function analyzetransparency(transparencyvalue)
- local tvalue = transparencyvalue and tonumber(transparencyvalue)
- return tvalue and pdftransparencyvalue(tvalue) or nil
-end
-
--- Attachments
-local nofattachments = 0
-local attachments = { }
-local filestreams = { }
-local referenced = { }
-local ignorereferenced = true -- fuzzy pdf spec .. twice in attachment list, can become an option
-local tobesavedobjrefs = utilities.storage.allocate()
-local collectedobjrefs = utilities.storage.allocate()
-
-local fileobjreferences = {
- collected = collectedobjrefs,
- tobesaved = tobesavedobjrefs,
-}
-
-job.fileobjreferences = fileobjreferences
-
-local function initializer()
- collectedobjrefs = job.fileobjreferences.collected or { }
- tobesavedobjrefs = job.fileobjreferences.tobesaved or { }
-end
-
-job.register('job.fileobjreferences.collected', tobesavedobjrefs, initializer)
-
-local function flushembeddedfiles()
- if next(filestreams) then
- local e = pdfarray()
- for tag, reference in next, filestreams do
- if not reference then
- report_attachment("unreferenced file, tag %a",tag)
- elseif referenced[tag] == "hidden" then
- e[#e+1] = pdfstring(tag)
- e[#e+1] = reference -- already a reference
- else
- -- messy spec ... when annot not in named else twice in menu list acrobat
- end
- end
- lpdf.addtonames("EmbeddedFiles",pdfreference(pdfflushobject(pdfdictionary{ Names = e })))
- end
-end
-
-lpdf.registerdocumentfinalizer(flushembeddedfiles,"embeddedfiles")
-
-function codeinjections.embedfile(specification)
- local data = specification.data
- local filename = specification.file
- local name = specification.name or ""
- local title = specification.title or ""
- local hash = specification.hash or filename
- local keepdir = specification.keepdir -- can change
- local usedname = specification.usedname
- local filetype = specification.filetype
- if filename == "" then
- filename = nil
- end
- if data then
- local r = filestreams[hash]
- if r == false then
- return nil
- elseif r then
- return r
- elseif not filename then
- filename = specification.tag
- if not filename or filename == "" then
- filename = specification.registered
- end
- if not filename or filename == "" then
- filename = hash
- end
- end
- else
- if not filename then
- return nil
- end
- local r = filestreams[hash]
- if r == false then
- return nil
- elseif r then
- return r
- else
- local foundname = resolvers.findbinfile(filename) or ""
- if foundname == "" or not lfs.isfile(foundname) then
- filestreams[filename] = false
- return nil
- else
- specification.foundname = foundname
- end
- end
- end
- -- needs to cleaned up:
- usedname = usedname ~= "" and usedname or filename or name
- local basename = keepdir == true and usedname or file.basename(usedname)
- local basename = gsub(basename,"%./","")
- local savename = name ~= "" and name or basename
- if not filetype or filetype == "" then
- filetype = name and (filename and file.suffix(filename)) or "txt"
- end
- savename = file.addsuffix(savename,filetype) -- type is mandate for proper working in viewer
- local mimetype = specification.mimetype
- local a = pdfdictionary {
- Type = pdfconstant("EmbeddedFile"),
- Subtype = mimetype and mimetype ~= "" and pdfconstant(mimetype) or nil,
- }
- local f
- if data then
- f = pdfflushstreamobject(data,a)
- specification.data = true -- signal that still data but already flushed
- else
- local foundname = specification.foundname or filename
- f = pdfflushstreamfileobject(foundname,a)
- end
- local d = pdfdictionary {
- Type = pdfconstant("Filespec"),
- F = pdfstring(savename),
- UF = pdfstring(savename),
- EF = pdfdictionary { F = pdfreference(f) },
- Desc = title ~= "" and pdfunicode(title) or nil,
- -- AFRelationship = pdfconstant("Source"), -- some day maybe, not mandate
- }
- local r = pdfreference(pdfflushobject(d))
- filestreams[hash] = r
- return r
-end
-
-function nodeinjections.attachfile(specification)
- local registered = specification.registered or "<unset>"
- local data = specification.data
- local hash
- local filename
- if data then
- hash = md5.HEX(data)
- else
- filename = specification.file
- if not filename or filename == "" then
- report_attachment("no file specified, using registered %a instead",registered)
- filename = registered
- specification.file = registered
- end
- local foundname = resolvers.findbinfile(filename) or ""
- if foundname == "" or not lfs.isfile(foundname) then
- report_attachment("invalid filename %a, ignoring registered %a",filename,registered)
- return nil
- else
- specification.foundname = foundname
- end
- hash = filename
- end
- specification.hash = hash
- nofattachments = nofattachments + 1
- local registered = specification.registered or ""
- local title = specification.title or ""
- local subtitle = specification.subtitle or ""
- local author = specification.author or ""
- if registered == "" then
- registered = filename
- end
- if author == "" and title ~= "" then
- author = title
- title = filename or ""
- end
- if author == "" then
- author = filename or "<unknown>"
- end
- if title == "" then
- title = registered
- end
- local aref = attachments[registered]
- if not aref then
- aref = codeinjections.embedfile(specification)
- attachments[registered] = aref
- end
- local reference = specification.reference
- if reference and aref then
- tobesavedobjrefs[reference] = aref[1]
- end
- if not aref then
- report_attachment("skipping attachment, registered %a",registered)
- -- already reported
- elseif specification.method == v_hidden then
- referenced[hash] = "hidden"
- else
- referenced[hash] = "annotation"
- local name, appearance = analyzesymbol(specification.symbol,attachment_symbols)
- local d = pdfdictionary {
- Subtype = pdfconstant("FileAttachment"),
- FS = aref,
- Contents = pdfunicode(title),
- Name = name,
- NM = pdfstring(format("attachment:%s",nofattachments)),
- T = author ~= "" and pdfunicode(author) or nil,
- Subj = subtitle ~= "" and pdfunicode(subtitle) or nil,
- C = analyzecolor(specification.colorvalue,specification.colormodel),
- CA = analyzetransparency(specification.transparencyvalue),
- AP = appearance,
- OC = analyzelayer(specification.layer),
- }
- local width, height, depth = specification.width or 0, specification.height or 0, specification.depth
- local box = hpack_node(nodeinjections.annotation(width,height,depth,d()))
- box.width, box.height, box.depth = width, height, depth
- return box
- end
-end
-
-function codeinjections.attachmentid(filename) -- not used in context
- return filestreams[filename]
-end
-
-local nofcomments, usepopupcomments, stripleading = 0, false, true
-
-local defaultattributes = {
- ["xmlns"] = "http://www.w3.org/1999/xhtml",
- ["xmlns:xfa"] = "http://www.xfa.org/schema/xfa-data/1.0/",
- ["xfa:contentType"] = "text/html",
- ["xfa:APIVersion"] = "Acrobat:8.0.0",
- ["xfa:spec"] = "2.4",
-}
-
-local function checkcontent(text,option)
- if option and option.xml then
- local root = xml.convert(text)
- if root and not root.er then
- xml.checkbom(root)
- local body = xml.first(root,"/body")
- if body then
- local at = body.at
- for k, v in next, defaultattributes do
- if not at[k] then
- at[k] = v
- end
- end
- -- local content = xml.textonly(root)
- local richcontent = xml.tostring(root)
- return nil, pdfunicode(richcontent)
- end
- end
- end
- return pdfunicode(text)
-end
-
-function nodeinjections.comment(specification) -- brrr: seems to be done twice
- nofcomments = nofcomments + 1
- local text = stripstring(specification.data or "")
- if stripleading then
- text = gsub(text,"[\n\r] *","\n")
- end
- local name, appearance = analyzesymbol(specification.symbol,comment_symbols)
- local tag = specification.tag or "" -- this is somewhat messy as recent
- local title = specification.title or "" -- versions of acrobat see the title
- local subtitle = specification.subtitle or "" -- as author
- local author = specification.author or ""
- local option = settings_to_hash(specification.option or "")
- if author == "" then
- if title == "" then
- title = tag
- end
- else
- if subtitle == "" then
- subtitle = title
- elseif title ~= "" then
- subtitle = subtitle .. ", " .. title
- end
- title = author
- end
- local content, richcontent = checkcontent(text,option)
- local d = pdfdictionary {
- Subtype = pdfconstant("Text"),
- Open = option[v_max] and pdfboolean(true) or nil,
- Contents = content,
- RC = richcontent,
- T = title ~= "" and pdfunicode(title) or nil,
- Subj = subtitle ~= "" and pdfunicode(subtitle) or nil,
- C = analyzecolor(specification.colorvalue,specification.colormodel),
- CA = analyzetransparency(specification.transparencyvalue),
- OC = analyzelayer(specification.layer),
- Name = name,
- NM = pdfstring(format("comment:%s",nofcomments)),
- AP = appearance,
- }
- local width, height, depth = specification.width or 0, specification.height or 0, specification.depth
- local box
- if usepopupcomments then
- -- rather useless as we can hide/vide
- local nd = pdfreserveobject()
- local nc = pdfreserveobject()
- local c = pdfdictionary {
- Subtype = pdfconstant("Popup"),
- Parent = pdfreference(nd),
- }
- d.Popup = pdfreference(nc)
- box = hpack_node(
- nodeinjections.annotation(0,0,0,d(),nd),
- nodeinjections.annotation(width,height,depth,c(),nc)
- )
- else
- box = hpack_node(nodeinjections.annotation(width,height,depth,d()))
- end
- box.width, box.height, box.depth = width, height, depth -- redundant
- return box
-end
-
--- rendering stuff
---
--- object_1 -> <</Type /Rendition /S /MR /C << /Type /MediaClip ... >> >>
--- object_2 -> <</Type /Rendition /S /MR /C << /Type /MediaClip ... >> >>
--- rendering -> <</Type /Rendition /S /MS [objref_1 objref_2]>>
---
--- we only work foreward here (currently)
--- annotation is to be packed at the tex end
-
--- aiff audio/aiff
--- au audio/basic
--- avi video/avi
--- mid audio/midi
--- mov video/quicktime
--- mp3 audio/x-mp3 (mpeg)
--- mp4 audio/mp4
--- mp4 video/mp4
--- mpeg video/mpeg
--- smil application/smil
--- swf application/x-shockwave-flash
-
--- P media play parameters (evt /BE for controls etc
--- A boolean (audio)
--- C boolean (captions)
--- O boolean (overdubs)
--- S boolean (subtitles)
--- PL pdfconstant("ADBE_MCI"),
-
--- F = flags,
--- T = title,
--- Contents = rubish,
--- AP = irrelevant,
-
--- sound is different, no window (or zero) so we need to collect them and
--- force them if not set
-
-local ms, mu, mf = { }, { }, { }
-
-local function delayed(label)
- local a = pdfreserveobject()
- mu[label] = a
- return pdfreference(a)
-end
-
-local function insertrenderingwindow(specification)
- local label = specification.label
- -- local openpage = specification.openpage
- -- local closepage = specification.closepage
- if specification.option == v_auto then
- if openpageaction then
- -- \handlereferenceactions{\v!StartRendering{#2}}
- end
- if closepageaction then
- -- \handlereferenceactions{\v!StopRendering {#2}}
- end
- end
- local actions = nil
- if openpage or closepage then
- actions = pdfdictionary {
- PO = (openpage and lpdfaction(openpage )) or nil,
- PC = (closepage and lpdfaction(closepage)) or nil,
- }
- end
- local page = tonumber(specification.page) or texgetcount("realpageno") -- todo
- local r = mu[label] or pdfreserveobject() -- why the reserve here?
- local a = pdfdictionary {
- S = pdfconstant("Rendition"),
- R = mf[label],
- OP = 0,
- AN = pdfreference(r),
- }
- local bs, bc = pdfborder()
- local d = pdfdictionary {
- Subtype = pdfconstant("Screen"),
- P = pdfreference(pdfpagereference(page)),
- A = a, -- needed in order to make the annotation clickable (i.e. don't bark)
- Border = bs,
- C = bc,
- AA = actions,
- }
- local width = specification.width or 0
- local height = specification.height or 0
- if height == 0 or width == 0 then
- -- todo: sound needs no window
- end
- write_node(nodeinjections.annotation(width,height,0,d(),r)) -- save ref
- return pdfreference(r)
-end
-
--- some dictionaries can have a MH (must honor) or BE (best effort) capsule
-
-local function insertrendering(specification)
- local label = specification.label
- local option = settings_to_hash(specification.option)
- if not mf[label] then
- local filename = specification.filename
- local isurl = find(filename,"://",1,true)
- -- local start = pdfdictionary {
- -- Type = pdfconstant("MediaOffset"),
- -- S = pdfconstant("T"), -- time
- -- T = pdfdictionary { -- time
- -- Type = pdfconstant("Timespan"),
- -- S = pdfconstant("S"),
- -- V = 3, -- time in seconds
- -- },
- -- }
- -- local start = pdfdictionary {
- -- Type = pdfconstant("MediaOffset"),
- -- S = pdfconstant("F"), -- frame
- -- F = 100 -- framenumber
- -- }
- -- local start = pdfdictionary {
- -- Type = pdfconstant("MediaOffset"),
- -- S = pdfconstant("M"), -- mark
- -- M = "somemark",
- -- }
- -- local parameters = pdfdictionary {
- -- BE = pdfdictionary {
- -- B = start,
- -- }
- -- }
- -- local parameters = pdfdictionary {
- -- Type = pdfconstant(MediaPermissions),
- -- TF = pdfstring("TEMPALWAYS") }, -- TEMPNEVER TEMPEXTRACT TEMPACCESS TEMPALWAYS
- -- }
- local descriptor = pdfdictionary {
- Type = pdfconstant("Filespec"),
- F = filename,
- }
- if isurl then
- descriptor.FS = pdfconstant("URL")
- elseif option[v_embed] then
- descriptor.EF = codeinjections.embedfile { file = filename }
- end
- local clip = pdfdictionary {
- Type = pdfconstant("MediaClip"),
- S = pdfconstant("MCD"),
- N = label,
- CT = specification.mime,
- Alt = pdfarray { "", "file not found" }, -- language id + message
- D = pdfreference(pdfflushobject(descriptor)),
- -- P = pdfreference(pdfflushobject(parameters)),
- }
- local rendition = pdfdictionary {
- Type = pdfconstant("Rendition"),
- S = pdfconstant("MR"),
- N = label,
- C = pdfreference(pdfflushobject(clip)),
- }
- mf[label] = pdfreference(pdfflushobject(rendition))
- end
-end
-
-local function insertrenderingobject(specification) -- todo
- local label = specification.label
- if not mf[label] then
- report_media("unknown medium, label %a",label)
- local clip = pdfdictionary { -- does not work that well one level up
- Type = pdfconstant("MediaClip"),
- S = pdfconstant("MCD"),
- N = label,
- D = pdfreference(unknown), -- not label but objectname, hm .. todo?
- }
- local rendition = pdfdictionary {
- Type = pdfconstant("Rendition"),
- S = pdfconstant("MR"),
- N = label,
- C = pdfreference(pdfflushobject(clip)),
- }
- mf[label] = pdfreference(pdfflushobject(rendition))
- end
-end
-
-function codeinjections.processrendering(label)
- local specification = interactions.renderings.rendering(label)
- if not specification then
- -- error
- elseif specification.type == "external" then
- insertrendering(specification)
- else
- insertrenderingobject(specification)
- end
-end
-
-function codeinjections.insertrenderingwindow(specification)
- local label = specification.label
- codeinjections.processrendering(label)
- ms[label] = insertrenderingwindow(specification)
-end
-
-local function set(operation,arguments)
- codeinjections.processrendering(arguments)
- return pdfdictionary {
- S = pdfconstant("Rendition"),
- OP = operation,
- R = mf[arguments],
- AN = ms[arguments] or delayed(arguments),
- }
-end
-
-function executers.startrendering (arguments) return set(0,arguments) end
-function executers.stoprendering (arguments) return set(1,arguments) end
-function executers.pauserendering (arguments) return set(2,arguments) end
-function executers.resumerendering(arguments) return set(3,arguments) end