diff options
Diffstat (limited to 'Master/texmf-dist/tex/context/base/mkiv/lpdf-fld.lua')
-rw-r--r-- | Master/texmf-dist/tex/context/base/mkiv/lpdf-fld.lua | 180 |
1 files changed, 111 insertions, 69 deletions
diff --git a/Master/texmf-dist/tex/context/base/mkiv/lpdf-fld.lua b/Master/texmf-dist/tex/context/base/mkiv/lpdf-fld.lua index 73de5eaf60d..983be508f2c 100644 --- a/Master/texmf-dist/tex/context/base/mkiv/lpdf-fld.lua +++ b/Master/texmf-dist/tex/context/base/mkiv/lpdf-fld.lua @@ -103,7 +103,7 @@ local pdf_tx = pdfconstant("Tx") local pdf_sig = pdfconstant("Sig") local pdf_ch = pdfconstant("Ch") local pdf_btn = pdfconstant("Btn") ------ pdf_yes = pdfconstant("Yes") +local pdf_yes = pdfconstant("Yes") local pdf_off = pdfconstant("Off") local pdf_p = pdfconstant("P") -- None Invert Outline Push local pdf_n = pdfconstant("N") -- None Invert Outline Push @@ -341,10 +341,10 @@ local function fieldsurrounding(specification) alternative, a = "tf", s.tf end local tag = fontstyle .. fontalternative - fontsize = todimen(fontsize) - fontsize = fontsize and (bpfactor * fontsize) or 12 + fontsize = todimen(fontsize) + fontsize = fontsize and (bpfactor * fontsize) or 12 fontraise = 0.1 * fontsize -- todo: figure out what the natural one is and compensate for strutdp - local fontcode = formatters["%0.4f Tf %0.4f Ts"](fontsize,fontraise) + local fontcode = formatters["%0.4F Tf %0.4F Ts"](fontsize,fontraise) -- we could test for colorvalue being 1 (black) and omit it then local colorcode = pdfcolor(3,colorvalue) -- we force an rgb color space if trace_fields then @@ -360,14 +360,16 @@ local function fieldsurrounding(specification) return tostring(stream) end +-- Can we use any font? + codeinjections.fieldsurrounding = fieldsurrounding local function registerfonts() if next(usedfonts) then checkpdfdocencoding() -- already done - local d = pdfdictionary() - local pdffonttype, pdffontsubtype = pdfconstant("Font"), pdfconstant("Type1") - -- for tag, name in next, usedfonts do + local pdffontlist = pdfdictionary() + local pdffonttype = pdfconstant("Font") + local pdffontsubtype = pdfconstant("Type1") for tag, name in sortedhash(usedfonts) do local f = pdfdictionary { Type = pdffonttype, @@ -376,9 +378,9 @@ local function registerfonts() BaseFont = pdfconstant(name), Encoding = pdfdocencodingvector, } - d[tag] = pdfreference(pdfflushobject(f)) + pdffontlist[tag] = pdfreference(pdfflushobject(f)) end - return d + return pdffontlist end end @@ -386,7 +388,7 @@ end local function fieldappearances(specification) -- todo: caching - local values = specification.values + local values = specification.values local default = specification.default -- todo if not values then -- error @@ -402,22 +404,51 @@ local function fieldappearances(specification) n, r, d = v[1], v[2], v[3] end local appearance = pdfdictionary { - N = registeredsymbol(n), R = registeredsymbol(r), D = registeredsymbol(d), + N = registeredsymbol(n), + R = registeredsymbol(r), + D = registeredsymbol(d), } return pdfshareobjectreference(appearance) -- return pdfreference(pdfflushobject(appearance)) end -local YesorOn = "Yes" -- somehow On is not always working out well any longer (why o why this change) - --- beware ... maybe we should have unique /Yes1 ... we will probably --- change this one too. +-- The rendering part of form support has always been crappy and didn't really +-- improve over time. Did bugs become features? Who knows. Why provide for instance +-- control over appearance and then ignore it when the mouse clicks someplace else. +-- Strangely enough a lot of effort went into JavaScript support while basic +-- appearance control of checkboxes stayed poor. I found this link when googling for +-- conformation after the n^th time looking into this behaviour: +-- +-- https://stackoverflow.com/questions/15479855/pdf-appearance-streams-checkbox-not-shown-correctly-after-focus-lost +-- +-- ... "In particular check boxes, therefore, whenever not interacting with the user, shall +-- be displayed using their normal captions, not their appearances." -- --- TODO: the same as radio .. play safe and use different names. +-- So: don't use check boxes. In fact, even radio buttons can have these funny "flash some +-- funny symbol" side effect when clocking on them. I tried all combinations if /H and /AP +-- and /AS and ... Because (afaiks) the acrobat interface assumes that one uses dingbats no +-- one really cared about getting custom appeances done well. This erratic behaviour might +-- as well be the reason why no open source viewer ever bothered implementing forms. It's +-- probably also why most forms out there look kind of bad. + +local function fieldstates_precheck(specification) + local values = specification.values + local default = specification.default + if not values or values == "" then + return + end + local yes = settings_to_array(values)[1] + local yesshown, yesvalue = lpegmatch(splitter,yes) + if not (yesshown and yesvalue) then + yesshown = yes + end + return default == settings_to_array(yesshown)[1] and pdf_yes or pdf_off +end -local function fieldstates_check(specification,forceyes,values,default,yesdefault) +local function fieldstates_check(specification) -- we don't use Opt here (too messy for radio buttons) - local values, default = values or specification.values, default or specification.default + local values = specification.values + local default = specification.default if not values or values == "" then -- error return @@ -459,28 +490,27 @@ local function fieldstates_check(specification,forceyes,values,default,yesdefaul if not offvalue then offvalue = offn end - if forceyes == true then - forceyes = YesorOn -- spec likes Yes more but we've used On for ages now - else - -- false or string - end if default == yesn then - default = pdfconstant(forceyes or yesn) + default = pdf_yes + yesvalue = yesvalue == yesn and "Yes" or "Off" else - default = pdf_off + default = pdf_off + yesvalue = "Off" end local appearance - if false then -- needs testing + -- if false then + if true then + -- needs testing appearance = pdfdictionary { -- maybe also cache components - N = pdfshareobjectreference(pdfdictionary { [forceyes or yesn] = registeredsymbol(yesn), Off = registeredsymbol(offn) }), - R = pdfshareobjectreference(pdfdictionary { [forceyes or yesr] = registeredsymbol(yesr), Off = registeredsymbol(offr) }), - D = pdfshareobjectreference(pdfdictionary { [forceyes or yesd] = registeredsymbol(yesd), Off = registeredsymbol(offd) }), + N = pdfshareobjectreference(pdfdictionary { Yes = registeredsymbol(yesn), Off = registeredsymbol(offn) }), + R = pdfshareobjectreference(pdfdictionary { Yes = registeredsymbol(yesr), Off = registeredsymbol(offr) }), + D = pdfshareobjectreference(pdfdictionary { Yes = registeredsymbol(yesd), Off = registeredsymbol(offd) }), } else appearance = pdfdictionary { -- maybe also cache components - N = pdfdictionary { [forceyes or yesn] = registeredsymbol(yesn), Off = registeredsymbol(offn) }, - R = pdfdictionary { [forceyes or yesr] = registeredsymbol(yesr), Off = registeredsymbol(offr) }, - D = pdfdictionary { [forceyes or yesd] = registeredsymbol(yesd), Off = registeredsymbol(offd) } + N = pdfdictionary { Yes = registeredsymbol(yesn), Off = registeredsymbol(offn) }, + R = pdfdictionary { Yes = registeredsymbol(yesr), Off = registeredsymbol(offr) }, + D = pdfdictionary { Yes = registeredsymbol(yesd), Off = registeredsymbol(offd) } } end local appearanceref = pdfshareobjectreference(appearance) @@ -488,12 +518,11 @@ local function fieldstates_check(specification,forceyes,values,default,yesdefaul return appearanceref, default, yesvalue end --- It looks like there is always a (MK related) symbol used and that --- the appearances are only used as ornaments behind a symbol. So, --- contrary to what we did when widgets showed up, we now limit --- ourself to more dumb definitions. Especially when highlighting is --- enabled weird interferences happen. So, we play safe (some nice code --- has been removed that worked well till recently). +-- It looks like there is always a (MK related) symbol used and that the appearances +-- are only used as ornaments behind a symbol. So, contrary to what we did when +-- widgets showed up, we now limit ourself to more dumb definitions. Especially when +-- highlighting is enabled weird interferences happen. So, we play safe (some nice +-- code has been removed that worked well till recently). local function fieldstates_radio(specification,name,parent) local values = values or specification.values @@ -572,7 +601,7 @@ local function fieldstates_radio(specification,name,parent) return appearanceref, default, yesvalue end -local function fielddefault(field) +local function fielddefault(field,pdf_yes) local default = field.default if not default or default == "" then local values = settings_to_array(field.values) @@ -581,12 +610,12 @@ local function fielddefault(field) if not default or default == "" then return pdf_off else - return pdfconstant(default) + return pdf_yes or pdfconstant(default) end end local function fieldoptions(specification) - local values = specification.values + local values = specification.values local default = specification.default if values then local v = settings_to_array(values) @@ -790,7 +819,9 @@ function codeinjections.definefield(specification) end function codeinjections.clonefield(specification) -- obsolete - local p, c, v = specification.parent, specification.children, specification.alternative + local p = specification.parent + local c = specification.children + local v = specification.alternative if not p or not c then if trace_fields then report_fields("invalid clone, children %a, parent %a, alternative %a",c,p,v) @@ -874,7 +905,8 @@ local function enhance(specification,option) return specification end --- finish +-- finish (if we also collect parents we can inline the kids which is +-- more efficient ... but hardly anyone used widgets so ...) local collected = pdfarray() local forceencoding = false @@ -949,14 +981,14 @@ end local function save_parent(field,specification,d,hasopt) local kidsnum = pdfreserveobject() - d.Kids = pdfreference(kidsnum) + d.Kids = pdfreference(kidsnum) field.kidsnum = kidsnum - field.kids = pdfarray() + field.kids = pdfarray() if hasopt then local optnum = pdfreserveobject() - d.Opt = pdfreference(optnum) + d.Opt = pdfreference(optnum) field.optnum = optnum - field.opt = pdfarray() + field.opt = pdfarray() end local pnum = pdfflushobject(d) field.pobj = pnum @@ -972,16 +1004,21 @@ local function save_kid(field,specification,d,optname) opt[#opt+1] = optname end end - local width, height, depth = specification.width or 0, specification.height or 0, specification.depth + local width = specification.width or 0 + local height = specification.height or 0 + local depth = specification.depth or 0 local box = hpack_node(nodeinjections.annotation(width,height,depth,d(),kn)) - box.width, box.height, box.depth = width, height, depth -- redundant + -- redundant + box.width = width + box.height = height + box.depth = depth return box end local function makelineparent(field,specification) - local text = pdfunicode(field.default) + local text = pdfunicode(field.default) local length = tonumber(specification.length or 0) or 0 - local d = pdfdictionary { + local d = pdfdictionary { Subtype = pdf_widget, T = pdfunicode(specification.title), F = fieldplus(specification), @@ -999,7 +1036,8 @@ local function makelineparent(field,specification) end local function makelinechild(name,specification) - local field, parent = clones[name], nil + local field = clones[name] + local parent = nil if field then parent = fields[field.parent] if not parent.pobj then @@ -1010,7 +1048,7 @@ local function makelinechild(name,specification) end else parent = fields[name] - field = parent + field = parent if not parent.pobj then if trace_fields then report_fields("using parent text %a",name) @@ -1047,9 +1085,9 @@ end -- copy of line ... probably also needs a /Lock local function makesignatureparent(field,specification) - local text = pdfunicode(field.default) + local text = pdfunicode(field.default) local length = tonumber(specification.length or 0) or 0 - local d = pdfdictionary { + local d = pdfdictionary { Subtype = pdf_widget, T = pdfunicode(specification.title), F = fieldplus(specification), @@ -1067,7 +1105,8 @@ local function makesignatureparent(field,specification) end local function makesignaturechild(name,specification) - local field, parent = clones[name], nil + local field = clones[name] + local parent = nil if field then parent = fields[field.parent] if not parent.pobj then @@ -1078,7 +1117,7 @@ local function makesignaturechild(name,specification) end else parent = fields[name] - field = parent + field = parent if not parent.pobj then if trace_fields then report_fields("using parent text %a",name) @@ -1124,7 +1163,8 @@ local function makechoiceparent(field,specification) end local function makechoicechild(name,specification) - local field, parent = clones[name], nil + local field = clones[name] + local parent = nil if field then parent = fields[field.parent] if not parent.pobj then @@ -1135,7 +1175,7 @@ local function makechoicechild(name,specification) end else parent = fields[name] - field = parent + field = parent if not parent.pobj then if trace_fields then report_fields("using parent choice %a",name) @@ -1169,20 +1209,22 @@ function methods.combo(name,specification) end local function makecheckparent(field,specification) + local default = fieldstates_precheck(field) local d = pdfdictionary { T = pdfunicode(specification.title), -- todo: when tracing use a string F = fieldplus(specification), Ff = fieldflag(specification), OC = fieldlayer(specification), - AA = fieldactions(specification), + AA = fieldactions(specification), -- can be shared FT = pdf_btn, - V = fielddefault(field), + V = fielddefault(field,default), } save_parent(field,specification,d,true) end local function makecheckchild(name,specification) - local field, parent = clones[name], nil + local field = clones[name] + local parent = nil if field then parent = fields[field.parent] if not parent.pobj then @@ -1193,7 +1235,7 @@ local function makecheckchild(name,specification) end else parent = fields[name] - field = parent + field = parent if not parent.pobj then if trace_fields then report_fields("using parent check %a",name) @@ -1209,7 +1251,7 @@ local function makecheckchild(name,specification) Parent = pdfreference(parent.pobj), F = fieldplus(specification), OC = fieldlayer(specification), - AA = fieldactions(specification), + AA = fieldactions(specification), -- can be shared H = pdf_n, } local fontsymbol = specification.fontsymbol @@ -1221,10 +1263,10 @@ local function makecheckchild(name,specification) d.MK = fieldrendering(specification) return save_kid(parent,specification,d) else - local appearance, default, value = fieldstates_check(field,true) + local appearance, default, value = fieldstates_check(field) d.AS = default d.AP = appearance - return save_kid(parent,specification,d,value) + return save_kid(parent,specification,d) end end @@ -1239,7 +1281,7 @@ local function makepushparent(field,specification) -- check if we can share with F = fieldplus(specification), Ff = fieldflag(specification), OC = fieldlayer(specification), - AA = fieldactions(specification), + AA = fieldactions(specification), -- can be shared FT = pdf_btn, AP = fieldappearances(field), H = pdf_p, @@ -1276,7 +1318,7 @@ local function makepushchild(name,specification) Parent = pdfreference(field.pobj), F = fieldplus(specification), OC = fieldlayer(specification), - AA = fieldactions(specification), + AA = fieldactions(specification), -- can be shared H = pdf_p, } if fontsymbol and fontsymbol ~= "" then @@ -1311,7 +1353,7 @@ end local function makeradiochild(name,specification) local field, parent = clones[name], nil if field then - field = radios[field.parent] + field = radios[field.parent] parent = fields[field.parent] if not parent.pobj then if trace_fields then |