diff options
Diffstat (limited to 'Master/texmf-dist/tex/context/base/mkiv/lpdf-epa.lua')
-rw-r--r-- | Master/texmf-dist/tex/context/base/mkiv/lpdf-epa.lua | 783 |
1 files changed, 124 insertions, 659 deletions
diff --git a/Master/texmf-dist/tex/context/base/mkiv/lpdf-epa.lua b/Master/texmf-dist/tex/context/base/mkiv/lpdf-epa.lua index 570d738817f..89b2c6e0e59 100644 --- a/Master/texmf-dist/tex/context/base/mkiv/lpdf-epa.lua +++ b/Master/texmf-dist/tex/context/base/mkiv/lpdf-epa.lua @@ -6,79 +6,49 @@ if not modules then modules = { } end modules ['lpdf-epa'] = { license = "see context related readme files" } --- Links can also have quadpoint +-- This is a rather experimental feature and the code will probably change. --- embedded files ... not bound to a page - -local type, tonumber, next = type, tonumber, next -local format, gsub, lower, find = string.format, string.gsub, string.lower, string.find +local type, tonumber = type, tonumber +local format, gsub, lower = string.format, string.gsub, string.lower local formatters = string.formatters -local concat, merged = table.concat, table.merged local abs = math.abs local expandname = file.expandname local allocate = utilities.storage.allocate -local bor, band = bit32.bor, bit32.band local isfile = lfs.isfile -local trace_links = false trackers.register("figures.links", function(v) trace_links = v end) -local trace_comments = false trackers.register("figures.comments", function(v) trace_comments = v end) -local trace_fields = false trackers.register("figures.fields", function(v) trace_fields = v end) -local trace_outlines = false trackers.register("figures.outlines", function(v) trace_outlines = v end) - -local report_link = logs.reporter("backend","link") -local report_comment = logs.reporter("backend","comment") -local report_field = logs.reporter("backend","field") -local report_outline = logs.reporter("backend","outline") - -local lpdf = lpdf -local epdf = epdf -local backends = backends -local context = context - -local nodeinjections = backends.pdf.nodeinjections - -local pdfarray = lpdf.array -local pdfdictionary = lpdf.dictionary -local pdfconstant = lpdf.constant -local pdfreserveobject = lpdf.reserveobject -local pdfreference = lpdf.reference +----- lpegmatch, lpegpatterns = lpeg.match, lpeg.patterns -local pdfcopyboolean = lpdf.copyboolean -local pdfcopyunicode = lpdf.copyunicode -local pdfcopyarray = lpdf.copyarray -local pdfcopydictionary = lpdf.copydictionary -local pdfcopynumber = lpdf.copynumber -local pdfcopyinteger = lpdf.copyinteger -local pdfcopystring = lpdf.copystring -local pdfcopyconstant = lpdf.copyconstant +local trace_links = false trackers.register("figures.links", function(v) trace_links = v end) +local trace_outlines = false trackers.register("figures.outliness", function(v) trace_outlines = v end) -local createimage = images.create -local embedimage = images.embed +local report_link = logs.reporter("backend","link") +local report_comment = logs.reporter("backend","comment") +local report_field = logs.reporter("backend","field") +local report_outline = logs.reporter("backend","outline") -local hpack_node = nodes.hpack +local epdf = epdf +local backends = backends +local lpdf = lpdf +local context = context -local loadpdffile = lpdf.epdf.load +local loadpdffile = lpdf.epdf.load -local nameonly = file.nameonly +local nameonly = file.nameonly -local variables = interfaces.variables -local codeinjections = backends.pdf.codeinjections ------ urlescaper = lpegpatterns.urlescaper ------ utftohigh = lpegpatterns.utftohigh -local escapetex = characters.filters.utf.private.escape +local variables = interfaces.variables +local codeinjections = backends.pdf.codeinjections +----- urlescaper = lpegpatterns.urlescaper +----- utftohigh = lpegpatterns.utftohigh +local escapetex = characters.filters.utf.private.escape -local bookmarks = structures.bookmarks +local bookmarks = structures.bookmarks -local maxdimen = 0x3FFFFFFF -- 2^30-1 - -local bpfactor = number.dimenfactors.bp +local maxdimen = 0x3FFFFFFF -- 2^30-1 local layerspec = { -- predefining saves time - "epdfcontent" + "epdflinks" } -local getpos = function() getpos = backends.codeinjections.getpos return getpos () end - local collected = allocate() local tobesaved = allocate() @@ -96,68 +66,6 @@ end job.register('job.embedded.collected',tobesaved,initializer) -local function validdocument(specification) - if figures and not specification then - specification = figures and figures.current() - specification = specification and specification.status - end - if specification then - local fullname = specification.fullname - local expanded = lower(expandname(fullname)) - -- we could add a check for duplicate page insertion - tobesaved[expanded] = true - --- but that is messy anyway so we forget about it - return specification, fullname, loadpdffile(fullname) -- costs time - end -end - -local function getmediasize(specification,pagedata) - local xscale = specification.xscale or 1 - local yscale = specification.yscale or 1 - ----- size = specification.size or "crop" -- todo - local mediabox = pagedata.MediaBox - local llx = mediabox[1] - local lly = mediabox[2] - local urx = mediabox[3] - local ury = mediabox[4] - local width = xscale * (urx - llx) -- \\overlaywidth, \\overlayheight - local height = yscale * (ury - lly) -- \\overlaywidth, \\overlayheight - return llx, lly, urx, ury, width, height, xscale, yscale -end - -local function getdimensions(annotation,llx,lly,xscale,yscale,width,height,report) - local rectangle = annotation.Rect - local a_llx = rectangle[1] - local a_lly = rectangle[2] - local a_urx = rectangle[3] - local a_ury = rectangle[4] - local x = xscale * (a_llx - llx) - local y = yscale * (a_lly - lly) - local w = xscale * (a_urx - a_llx) - local h = yscale * (a_ury - a_lly) - if w > width or h > height or w < 0 or h < 0 or abs(x) > (maxdimen/2) or abs(y) > (maxdimen/2) then - report("broken rectangle [%.6F %.6F %.6F %.6F] (max: %.6F)",a_llx,a_lly,a_urx,a_ury,maxdimen/2) - return - end - return x, y, w, h, a_llx, a_lly, a_urx, a_ury -end - -local layerused = false - -local function initializelayer(height,width) - if not layerused then - context.definelayer(layerspec, { height = height .. "bp", width = width .. "bp" }) - layerused = true - end -end - -function codeinjections.flushmergelayer() - if layerused then - context.flushlayer(layerspec) - layerused = false - end -end - local f_namespace = formatters["lpdf-epa-%s-"] local function makenamespace(filename) @@ -274,51 +182,82 @@ local function link_file(x,y,w,h,document,annotation) end end --- maybe handler per subtype and then one loop but then what about order ... - function codeinjections.mergereferences(specification) - local specification, fullname, document = validdocument(specification) + if figures and not specification then + specification = figures and figures.current() + specification = specification and specification.status + end + if not specification then + return "" + end + local fullname = specification.fullname + local expanded = lower(expandname(fullname)) + -- we could add a check for duplicate page insertion + tobesaved[expanded] = true + --- but that is messy anyway so we forget about it + local document = loadpdffile(fullname) -- costs time if not document then return "" end - local pagenumber = specification.page or 1 + local pagenumber = specification.page or 1 + local xscale = specification.yscale or 1 + local yscale = specification.yscale or 1 + local size = specification.size or "crop" -- todo local pagedata = document.pages[pagenumber] local annotations = pagedata and pagedata.Annots local namespace = makenamespace(fullname) local reference = namespace .. pagenumber - if annotations and #annotations > 0 then - local llx, lly, urx, ury, width, height, xscale, yscale = getmediasize(specification,pagedata,xscale,yscale) - initializelayer(height,width) - for i=1,#annotations do + if annotations and annotations.n > 0 then + local mediabox = pagedata.MediaBox + local llx = mediabox[1] + local lly = mediabox[2] + local urx = mediabox[3] + local ury = mediabox[4] + local width = xscale * (urx - llx) -- \\overlaywidth, \\overlayheight + local height = yscale * (ury - lly) -- \\overlaywidth, \\overlayheight + context.definelayer( { "epdflinks" }, { height = height.."bp" , width = width.."bp" }) + for i=1,annotations.n do local annotation = annotations[i] if annotation then - if annotation.Subtype == "Link" then + local subtype = annotation.Subtype + local rectangle = annotation.Rect + local a_llx = rectangle[1] + local a_lly = rectangle[2] + local a_urx = rectangle[3] + local a_ury = rectangle[4] + local x = xscale * (a_llx - llx) + local y = yscale * (a_lly - lly) + local w = xscale * (a_urx - a_llx) + local h = yscale * (a_ury - a_lly) + if subtype == "Link" then local a = annotation.A if not a then report_link("missing link annotation") + elseif w > width or h > height or w < 0 or h < 0 or abs(x) > (maxdimen/2) or abs(y) > (maxdimen/2) then + report_link("broken link rectangle [%.6F %.6F %.6F %.6F] (max: %.6F)",a_llx,a_lly,a_urx,a_ury,maxdimen/2) else - local x, y, w, h = getdimensions(annotation,llx,lly,xscale,yscale,width,height,report_link) - if x then - local linktype = a.S - if linktype == "GoTo" then - link_goto(x,y,w,h,document,annotation,pagedata,namespace) - elseif linktype == "GoToR" then - link_file(x,y,w,h,document,annotation) - elseif linktype == "URI" then - link_uri(x,y,w,h,document,annotation) - elseif trace_links then - report_link("unsupported link annotation %a",linktype) - end + local linktype = a.S + if linktype == "GoTo" then + link_goto(x,y,w,h,document,annotation,pagedata,namespace) + elseif linktype == "GoToR" then + link_file(x,y,w,h,document,annotation) + elseif linktype == "URI" then + link_uri(x,y,w,h,document,annotation) + elseif trace_links then + report_link("unsupported link annotation %a",linktype) end end + elseif trace_links then + report_link("unsupported annotation %a",subtype) end elseif trace_links then report_link("broken annotation, index %a",i) end end + context.flushlayer { "epdflinks" } end -- moved outside previous test - context.setgvalue("figurereference",reference) -- global, todo: setmacro + context.setgvalue("figurereference",reference) -- global if trace_links then report_link("setting figure reference to %a",reference) end @@ -331,527 +270,43 @@ function codeinjections.mergeviewerlayers(specification) if true then return end - local specification, fullname, document = validdocument(specification) - if not document then - return "" - end - local namespace = makenamespace(fullname) - local layers = document.layers - if layers then - for i=1,#layers do - local layer = layers[i] - if layer then - local tag = namespace .. gsub(layer," ",":") - local title = tag - if trace_links then - report_link("using layer %a",tag) - end - attributes.viewerlayers.define { -- also does some cleaning - tag = tag, -- todo: #3A or so - title = title, - visible = variables.start, - editable = variables.yes, - printable = variables.yes, - } - codeinjections.useviewerlayer(tag) - elseif trace_links then - report_link("broken layer, index %a",i) - end - end - end -end - --- It took a bit of puzzling and playing around to come to the following --- implementation. In the end it looks simple but as usual it takes a while --- to see what the specification (and implementation) boils down to. Lots of --- shared properties and such. The scaling took some trial and error as --- viewers differ. I had to extend some low level helpers to make it more --- comfortable. Hm, the specification is somewhat incomplete as some fields --- are permitted even if not mentioned so in the end we can share more code. --- --- If all works ok, we can get rid of some copies which saves time and space. - -local commentlike = { - Text = "text", - FreeText = "freetext", - Line = "line", - Square = "shape", - Circle = "shape", - Polygon = "poly", - PolyLine = "poly", - Highlight = "markup", - Underline = "markup", - Squiggly = "markup", - StrikeOut = "markup", - Caret = "text", - Stamp = "stamp", - Ink = "ink", - Popup = "popup", -} - -local function copyBS(v) -- dict can be shared - if v then - -- return pdfdictionary { - -- Type = copypdfconstant(V.Type), - -- W = copypdfnumber (V.W), - -- S = copypdfstring (V.S), - -- D = copypdfarray (V.D), - -- } - return copypdfdictionary(v) - end -end - -local function copyBE(v) -- dict can be shared - if v then - -- return pdfdictionary { - -- S = copypdfstring(V.S), - -- I = copypdfnumber(V.I), - -- } - return copypdfdictionary(v) - end -end - -local function copyBorder(v) -- dict can be shared - if v then - -- todo - return copypdfarray(v) - end -end - -local function copyPopup(v,references) - if v then - local p = references[v] - if p then - return pdfreference(p) - end - end -end - -local function copyParent(v,references) - if v then - local p = references[v] - if p then - return pdfreference(p) - end - end -end - -local function copyIRT(v,references) - if v then - local p = references[v] - if p then - return pdfreference(p) - end - end -end - -local function copyC(v) - if v then - -- todo: check color space - return pdfcopyarray(v) - end -end - -local function finalizer(d,xscale,yscale,a_llx,a_ury) - local q = d.QuadPoints or d.Vertices or d.CL - if q then - return function() - local h, v = pdfgetpos() -- already scaled - for i=1,#q,2 do - q[i] = xscale * q[i] + (h*bpfactor - xscale * a_llx) - q[i+1] = yscale * q[i+1] + (v*bpfactor - yscale * a_ury) - end - return d() - end - end - q = d.InkList or d.Path - if q then - return function() - local h, v = pdfgetpos() -- already scaled - for i=1,#q do - local q = q[i] - for i=1,#q,2 do - q[i] = xscale * q[i] + (h*bpfactor - xscale * a_llx) - q[i+1] = yscale * q[i+1] + (v*bpfactor - yscale * a_ury) - end - end - return d() - end - end - return d() -end - -local validstamps = { - Approved = true, - Experimental = true, - NotApproved = true, - AsIs = true, - Expired = true, - NotForPublicRelease = true, - Confidential = true, - Final = true, - Sold = true, - Departmental = true, - ForComment = true, - TopSecret = true, - Draft = true, - ForPublicRelease = true, -} - --- todo: we can use runtoks instead of steps - -local function validStamp(v) - local name = "Stamped" -- fallback - if v then - local ok = validstamps[v] - if ok then - name = ok - else - for k in next, validstamps do - if find(v,k.."$") then - name = k - validstamps[v] = k - break - end - end - end - end - -- we temporary return to \TEX: - context.predefinesymbol { name } - context.step() - -- beware, an error is not reported - return pdfconstant(name), codeinjections.analyzenormalsymbol(name) -end - -local annotationflags = lpdf.flags.annotations - -local function copyF(v,lock) -- todo: bxor 24 - if lock then - v = bor(v or 0,annotationflags.ReadOnly + annotationflags.Locked + annotationflags.LockedContents) - end - if v then - return pdfcopyinteger(v) - end -end - --- Speed is not really an issue so we don't optimize this code too much. In the end (after --- testing we end up with less code that we started with. - -function codeinjections.mergecomments(specification) - local specification, fullname, document = validdocument(specification) - if not document then - return "" + if not specification then + specification = figures and figures.current() + specification = specification and specification.status end - local pagenumber = specification.page or 1 - local pagedata = document.pages[pagenumber] - local annotations = pagedata and pagedata.Annots - if annotations and #annotations > 0 then - local llx, lly, urx, ury, width, height, xscale, yscale = getmediasize(specification,pagedata,xscale,yscale) - initializelayer(height,width) - -- - local lockflags = specification.lock -- todo: proper parameter - local references = { } - local usedpopups = { } - for i=1,#annotations do - local annotation = annotations[i] - if annotation then - local subtype = annotation.Subtype - if commentlike[subtype] then - references[annotation] = pdfreserveobject() - local p = annotation.Popup - if p then - usedpopups[p] = true - end - end - end - end - -- - for i=1,#annotations do - -- we keep the order - local annotation = annotations[i] - if annotation then - local reference = references[annotation] - if reference then - local subtype = annotation.Subtype - local kind = commentlike[subtype] - if kind ~= "popup" or usedpopups[annotation] then - local x, y, w, h, a_llx, a_lly, a_urx, a_ury = getdimensions(annotation,llx,lly,xscale,yscale,width,height,report_comment) - if x then - local voffset = h - local dictionary = pdfdictionary { - Subtype = pdfconstant (subtype), - -- common (skipped: P AP AS OC AF BM StructParent) - Contents = pdfcopyunicode(annotation.Contents), - NM = pdfcopystring (annotation.NM), - M = pdfcopystring (annotation.M), - F = copyF (annotation.F,lockflags), - C = copyC (annotation.C), - ca = pdfcopynumber (annotation.ca), - CA = pdfcopynumber (annotation.CA), - Lang = pdfcopystring (annotation.Lang), - -- also common - CreationDate = pdfcopystring (annotation.CreationDate), - T = pdfcopyunicode(annotation.T), - Subj = pdfcopyunicode(annotation.Subj), - -- border - Border = pdfcopyarray (annotation.Border), - BS = copyBS (annotation.BS), - BE = copyBE (annotation.BE), - -- sort of common - Popup = copyPopup (annotation.Popup,references), - RC = pdfcopyunicode(annotation.RC) -- string or stream - } - if kind == "markup" then - dictionary.IRT = copyIRT (annotation.IRT,references) - dictionary.RT = pdfconstant (annotation.RT) - dictionary.IT = pdfcopyconstant (annotation.IT) - dictionary.QuadPoints = pdfcopyarray (annotation.QuadPoints) - -- dictionary.RD = pdfcopyarray (annotation.RD) - elseif kind == "text" then - -- somehow F fails to view : /F 24 : bit4=nozoom bit5=norotate - dictionary.F = nil - dictionary.Open = pdfcopyboolean (annotation.Open) - dictionary.Name = pdfcopyunicode (annotation.Name) - dictionary.State = pdfcopystring (annotation.State) - dictionary.StateModel = pdfcopystring (annotation.StateModel) - dictionary.IT = pdfcopyconstant (annotation.IT) - dictionary.QuadPoints = pdfcopyarray (annotation.QuadPoints) - dictionary.RD = pdfcopyarray (annotation.RD) -- caret - dictionary.Sy = pdfcopyconstant (annotation.Sy) -- caret - voffset = 0 - elseif kind == "freetext" then - dictionary.DA = pdfcopystring (annotation.DA) - dictionary.Q = pdfcopyinteger (annotation.Q) - dictionary.DS = pdfcopystring (annotation.DS) - dictionary.CL = pdfcopyarray (annotation.CL) - dictionary.IT = pdfcopyconstant (annotation.IT) - dictionary.LE = pdfcopyconstant (annotation.LE) - -- dictionary.RC = pdfcopystring (annotation.RC) - elseif kind == "line" then - dictionary.LE = pdfcopyarray (annotation.LE) - dictionary.IC = pdfcopyarray (annotation.IC) - dictionary.LL = pdfcopynumber (annotation.LL) - dictionary.LLE = pdfcopynumber (annotation.LLE) - dictionary.Cap = pdfcopyboolean (annotation.Cap) - dictionary.IT = pdfcopyconstant (annotation.IT) - dictionary.LLO = pdfcopynumber (annotation.LLO) - dictionary.CP = pdfcopyconstant (annotation.CP) - dictionary.Measure = pdfcopydictionary(annotation.Measure) -- names - dictionary.CO = pdfcopyarray (annotation.CO) - voffset = 0 - elseif kind == "shape" then - dictionary.IC = pdfcopyarray (annotation.IC) - -- dictionary.RD = pdfcopyarray (annotation.RD) - voffset = 0 - elseif kind == "stamp" then - local name, appearance = validStamp(annotation.Name) - dictionary.Name = name - dictionary.AP = appearance - voffset = 0 - elseif kind == "ink" then - dictionary.InkList = pdfcopyarray (annotation.InkList) - elseif kind == "poly" then - dictionary.Vertices = pdfcopyarray (annotation.Vertices) - -- dictionary.LE = pdfcopyarray (annotation.LE) -- todo: names in array - dictionary.IC = pdfcopyarray (annotation.IC) - dictionary.IT = pdfcopyconstant (annotation.IT) - dictionary.Measure = pdfcopydictionary(annotation.Measure) - dictionary.Path = pdfcopyarray (annotation.Path) - -- dictionary.RD = pdfcopyarray (annotation.RD) - elseif kind == "popup" then - dictionary.Open = pdfcopyboolean (annotation.Open) - dictionary.Parent = copyParent (annotation.Parent,references) - voffset = 0 - end - if dictionary then - local locationspec = { - x = x .. "bp", - y = y .. "bp", - voffset = voffset .. "bp", - preset = "leftbottom", - } - local finalize = finalizer(dictionary,xscale,yscale,a_llx,a_ury) - context.setlayer(layerspec,locationspec,function() - context(hpack_node(nodeinjections.annotation(w/bpfactor,h/bpfactor,0,finalize,reference))) - end) - end + if specification then + local fullname = specification.fullname + local document = loadpdffile(fullname) + if document then + local namespace = makenamespace(fullname) + local layers = document.layers + if layers then + for i=1,layers.n do + local layer = layers[i] + if layer then + local tag = namespace .. gsub(layer," ",":") + local title = tag + if trace_links then + report_link("using layer %a",tag) end - else - -- report_comment("skipping annotation, index %a",i) + attributes.viewerlayers.define { -- also does some cleaning + tag = tag, -- todo: #3A or so + title = title, + visible = variables.start, + editable = variables.yes, + printable = variables.yes, + } + codeinjections.useviewerlayer(tag) + elseif trace_links then + report_link("broken layer, index %a",i) end end - elseif trace_comments then - report_comment("broken annotation, index %a",i) end end end - return namespace end -local widgetflags = lpdf.flags.widgets - -local function flagstoset(flag,flags) - local t = { } - if flags then - for k, v in next, flags do - if band(flag,v) ~= 0 then - t[k] = true - end - end - end - return t -end - --- BS : border style dict --- R : rotation 0 90 180 270 --- BG : background array --- CA : caption string --- RC : roll over caption --- AC : down caption --- I/RI/IX : icon streams --- IF : fit dictionary --- TP : text position number - --- Opt : array of texts --- TI : top index - --- V : value --- DV : default value --- DS : default string --- RV : rich --- Q : quadding (0=left 1=middle 2=right) - -function codeinjections.mergefields(specification) - local specification, fullname, document = validdocument(specification) - if not document then - return "" - end - local pagenumber = specification.page or 1 - local pagedata = document.pages[pagenumber] - local annotations = pagedata and pagedata.Annots - if annotations and #annotations > 0 then - local llx, lly, urx, ury, width, height, xscale, yscale = getmediasize(specification,pagedata,xscale,yscale) - initializelayer(height,width) - -- - for i=1,#annotations do - -- we keep the order - local annotation = annotations[i] - if annotation then - local subtype = annotation.Subtype - if subtype == "Widget" then - local parent = annotation.Parent or { } - local name = annotation.T or parent.T - local what = annotation.FT or parent.FT - if name and what then - local x, y, w, h, a_llx, a_lly, a_urx, a_ury = getdimensions(annotation,llx,lly,xscale,yscale,width,height,report_field) - if x then - x = x .. "bp" - y = y .. "bp" - local W, H = w, h - w = w .. "bp" - h = h .. "bp" - if trace_fields then - report_field("field %a, type %a, dx %s, dy %s, wd %s, ht %s",name,what,x,y,w,h) - end - local locationspec = { - x = x, - y = y, - preset = "leftbottom", - } - -- - local aflags = flagstoset(annotation.F or parent.F, annotationflags) - local wflags = flagstoset(annotation.Ff or parent.Ff, widgetflags) - if what == "Tx" then - -- DA DV F FT MaxLen MK Q T V | AA OC - if wflags.MultiLine then - wflags.MultiLine = nil - what = "text" - else - what = "line" - end - -- via context - local fieldspec = { - width = w, - height = h, - offset = variables.overlay, - frame = trace_links and variables.on or variables.off, - n = annotation.MaxLen or (parent and parent.MaxLen), - type = what, - option = concat(merged(aflags,wflags),","), - } - context.setlayer (layerspec,locationspec,function() - context.definefieldbody ( { name } , fieldspec ) - context.fieldbody ( { name } ) - end) - -- - elseif what == "Btn" then - if wflags.Radio or wflags.RadiosInUnison then - -- AP AS DA F Ff FT H MK T V | AA OC - wflags.Radio = nil - wflags.RadiosInUnison = nil - what = "radio" - elseif wflags.PushButton then - -- AP DA F Ff FT H MK T | AA OC - -- - -- Push buttons only have an appearance and some associated - -- actions so they are not worth copying. - -- - wflags.PushButton = nil - what = "push" - else - -- AP AS DA F Ff FT H MK T V | OC AA - what = "check" - -- direct - local AP = annotation.AP or (parent and parent.AP) - if AP then - local a = document.__xrefs__[AP] - if a and pdfe.copyappearance then - local o = pdfe.copyappearance(document,a) - if o then - AP = pdfreference(o) - end - end - end - local dictionary = pdfdictionary { - Subtype = pdfconstant("Widget"), - FT = pdfconstant("Btn"), - T = pdfcopyunicode(annotation.T or parent.T), - F = pdfcopyinteger(annotation.F or parent.F), - Ff = pdfcopyinteger(annotation.Ff or parent.Ff), - AS = pdfcopyconstant(annotation.AS or (parent and parent.AS)), - AP = AP and pdfreference(AP), - } - local finalize = dictionary() - context.setlayer(layerspec,locationspec,function() - context(hpack_node(nodeinjections.annotation(W/bpfactor,H/bpfactor,0,finalize))) - end) - -- - end - elseif what == "Ch" then - -- F Ff FT Opt T | AA OC (rest follows) - if wflags.PopUp then - wflags.PopUp = nil - if wflags.Edit then - wflags.Edit = nil - what = "combo" - else - what = "popup" - end - else - what = "choice" - end - elseif what == "Sig" then - what = "signature" - else - what = nil - end - end - end - end - end - end - end -end +-- new: for taco -- Beware, bookmarks can be in pdfdoc encoding or in unicode. However, in mkiv we -- write out the strings in unicode (hex). When we read them in, we check for a bom @@ -882,7 +337,7 @@ function codeinjections.getbookmarks(filename) local outlines = document.Catalog.Outlines local pages = document.pages - local nofpages = document.nofpages + local nofpages = pages.n -- we need to access once in order to initialize local destinations = document.destinations -- I need to check this destination analyzer with the one in annotations .. best share @@ -904,7 +359,7 @@ function codeinjections.getbookmarks(filename) entry.realpage = pagedata.number end elseif kind == "table" then - local pageref = #destination + local pageref = destination.n if pageref then local pagedata = pages[pageref] if pagedata then @@ -912,8 +367,8 @@ function codeinjections.getbookmarks(filename) end end end - -- elseif subtype then - -- report("unsupported bookmark action %a",subtype) + else + -- maybe end else local destination = current.Dest @@ -928,8 +383,6 @@ function codeinjections.getbookmarks(filename) local pagedata = destination and destination[1] if pagedata and pagedata.Type == "Page" then entry.realpage = pagedata.number - -- else - -- report("unsupported bookmark destination (no page)") end end end @@ -1018,6 +471,16 @@ function codeinjections.mergebookmarks(specification) end end +-- placeholders: + +function codeinjections.mergecomments(specification) + report_comment("unfinished experimental code, not used yet") +end + +function codeinjections.mergefields(specification) + report_field("unfinished experimental code, not used yet") +end + -- A bit more than a placeholder but in the same perspective as -- inclusion of comments and fields: -- @@ -1038,7 +501,7 @@ function codeinjections.getinfo(specification) local catalog = pdffile.Catalog local info = pdffile.Info local pages = pdffile.pages - local nofpages = pdffile.nofpages + local nofpages = pages.n if metadata then local m = catalog.Metadata if m then @@ -1062,8 +525,10 @@ function codeinjections.getinfo(specification) local media = nobox local page = pages[pagenumber] if page then - crop = page.CropBox or nobox - media = page.MediaBox or crop or nobox + crop = page.CropBox or nobox + media = page.MediaBox or crop or nobox + crop.n = nil -- nicer + media.n = nil -- nicer end local bbox = crop or media or nobox return { |