diff options
Diffstat (limited to 'Master/texmf-dist/tex/context/base/mkxl/lpdf-epa.lmt')
-rw-r--r-- | Master/texmf-dist/tex/context/base/mkxl/lpdf-epa.lmt | 177 |
1 files changed, 128 insertions, 49 deletions
diff --git a/Master/texmf-dist/tex/context/base/mkxl/lpdf-epa.lmt b/Master/texmf-dist/tex/context/base/mkxl/lpdf-epa.lmt index 26bb9f70318..7d1e54b650a 100644 --- a/Master/texmf-dist/tex/context/base/mkxl/lpdf-epa.lmt +++ b/Master/texmf-dist/tex/context/base/mkxl/lpdf-epa.lmt @@ -11,7 +11,7 @@ if not modules then modules = { } end modules ['lpdf-epa'] = { -- 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 format, gsub, lower, find, match = string.format, string.gsub, string.lower, string.find, string.match local formatters = string.formatters local concat, merged = table.concat, table.merged local abs = math.abs @@ -70,9 +70,8 @@ local escapetex = characters.filters.utf.private.escape local bookmarks = structures.bookmarks -local maxdimen = 0x3FFFFFFF -- 2^30-1 - -local bpfactor = number.dimenfactors.bp +local maxdimen <const> = tex.magicconstants.maxdimen +local bpfactor <const> = number.dimenfactors.bp local layerspec = { "epdfcontent" @@ -126,7 +125,7 @@ local function getmediasize(specification,pagedata) return llx, lly, urx, ury, width, height, xscale, yscale end -local function getdimensions(annotation,llx,lly,xscale,yscale,width,height,report) +local function getdimensions(annotation,llx,lly,xscale,yscale,width,height,report,minheight) local rectangle = annotation.Rect local a_llx = rectangle[1] local a_lly = rectangle[2] @@ -140,6 +139,13 @@ local function getdimensions(annotation,llx,lly,xscale,yscale,width,height,repor report("broken rectangle [%.6F %.6F %.6F %.6F] (max: %.6F)",a_llx,a_lly,a_urx,a_ury,maxdimen/2) return end + if minheight and minheight ~= 0 then + local dh = minheight - h + if dh > 0 then + y = y - dh/2 + h = h + dh + end + end return x, y, w, h, a_llx, a_lly, a_urx, a_ury end @@ -200,7 +206,7 @@ local function add_link(x,y,w,h,destination,what) ) end -local function link_goto(x,y,w,h,document,annotation,pagedata,namespace) +local function link_goto(x,y,w,h,document,annotation,pagedata,namespace,pageoffset) local a = annotation.A if a then local destination = a.D -- [ 18 0 R /Fit ] @@ -215,7 +221,12 @@ local function link_goto(x,y,w,h,document,annotation,pagedata,namespace) if pagedata then local destinationpage = pagedata.number if destinationpage then - add_link(x,y,w,h,namespace .. destinationpage,what) + if pageoffset then + destinationpage = "page(" .. (destinationpage+pageoffset) .. ")" + else + destinationpage = namespace .. destinationpage + end + add_link(x,y,w,h,destinationpage,what) end end end @@ -283,8 +294,32 @@ local function link_file(x,y,w,h,document,annotation) end -- maybe handler per subtype and then one loop but then what about order ... +-- +-- specification is normally nil + +local function getpageoffset(options) + if options then + for k in next, options do + local p = tonumber(match(k,"pageoffset:([%+%-]*%d+)")) + if p then + return p + end + end + end +end + +local function getminheight(options) + if options then + for k in next, options do + local p = tonumber(match(k,"minheight:([%+%-]*%d+)")) + if p then + return p + end + end + end +end -function codeinjections.mergereferences(specification) +function codeinjections.mergereferences(specification,options) local specification, fullname, document = validdocument(specification) if not document then return "" @@ -294,6 +329,8 @@ function codeinjections.mergereferences(specification) local annotations = pagedata and pagedata.Annots local namespace = makenamespace(fullname) local reference = namespace .. pagenumber + local pageoffset = getpageoffset(options) + local minheight = getminheight(options) if annotations and #annotations > 0 then local llx, lly, urx, ury, width, height, xscale, yscale = getmediasize(specification,pagedata,xscale,yscale) initializelayer(height,width) @@ -305,17 +342,18 @@ function codeinjections.mergereferences(specification) if not a then local d = annotation.Dest if d then - annotation.A = { S = "GoTo", D = d } -- no need for a dict + a = { S = "GoTo", D = d } -- no need for a dict + annotation.A = a end end if not a then report_link("missing link annotation") else - local x, y, w, h = getdimensions(annotation,llx,lly,xscale,yscale,width,height,report_link) + local x, y, w, h = getdimensions(annotation,llx,lly,xscale,yscale,width,height,report_link,minheight) if x then local linktype = a.S if linktype == "GoTo" then - link_goto(x,y,w,h,document,annotation,pagedata,namespace) + link_goto(x,y,w,h,document,annotation,pagedata,namespace,pageoffset) elseif linktype == "GoToR" then link_file(x,y,w,h,document,annotation) elseif linktype == "URI" then @@ -735,7 +773,7 @@ end -- RV : rich -- Q : quadding (0=left 1=middle 2=right) -function codeinjections.mergefields(specification) +function codeinjections.mergefields(specification,dataonly) local specification, fullname, document = validdocument(specification) if not document then return "" @@ -773,8 +811,8 @@ function codeinjections.mergefields(specification) preset = "leftbottom", } -- - local aflags = flagstoset(annotation.F or parent.F, annotationflags) - local wflags = flagstoset(annotation.Ff or parent.Ff, widgetflags) + local aflags = flagstoset(annotation.F or parent.F or 0, annotationflags) + local wflags = flagstoset(annotation.Ff or parent.Ff or 0, widgetflags) if what == "Tx" then -- DA DV F FT MaxLen MK Q T V | AA OC if wflags.MultiLine then @@ -783,21 +821,58 @@ function codeinjections.mergefields(specification) 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) - -- + local frame = trace_links and variables.on or variables.off + local default = annotation.V or "" + if default == "" then + local parent = annotation.Parent + if parent then + default = parent.V or "" + end + end + if dataonly then + if type(default) == "string" and default ~= "" then + local data = lpdf.epdf.parsecontent(tostring(annotation.DA or "") or "") or { } + local font = "Normal" + local size = "10bp" + for i=1,#data do + local d = data[i] + if d[3] == "Tf" then + font = d[1][2] + size = d[2][2] .. "bp" + break + end + end + local fieldspec = { + width = w, + height = h, + frame = frame, + -- + ["epdf:font"] = font, + ["epdf:size"] = size, + } +report_field("field %a, type %a, data %a",name,what,default) + context.setlayer (layerspec,locationspec,function() + context["epdf"..what.."field"](fieldspec,default) + end) + end + else + local fieldspec = { + width = w, + height = h, + offset = variables.overlay, + frame = frame, + n = annotation.MaxLen or (parent and parent.MaxLen), + type = what, + option = concat(merged(aflags,wflags),","), + default = default, + } + context.setlayer (layerspec,locationspec,function() + context.definefieldbody ( { name } , fieldspec ) + context.fieldbody ( { name } ) + end) + end elseif what == "Btn" then if wflags.Radio or wflags.RadiosInUnison then -- AP AS DA F Ff FT H MK T V | AA OC @@ -816,30 +891,34 @@ function codeinjections.mergefields(specification) -- 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) + if dataonly then + report_field("field %a, type %a, todo: render value",name,what) + else + 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), + -- V = annotation.V, + } + local finalize = dictionary() + context.setlayer(layerspec,locationspec,function() + context(hpack_node(nodeinjections.annotation(W/bpfactor,H/bpfactor,0,finalize))) + 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) |