summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/context/base/mkiv/lpdf-epa.lua
diff options
context:
space:
mode:
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.lua783
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 {