diff options
Diffstat (limited to 'Master/texmf-dist/tex/context/base/lpdf-ini.lua')
-rw-r--r-- | Master/texmf-dist/tex/context/base/lpdf-ini.lua | 420 |
1 files changed, 270 insertions, 150 deletions
diff --git a/Master/texmf-dist/tex/context/base/lpdf-ini.lua b/Master/texmf-dist/tex/context/base/lpdf-ini.lua index e0ffd40521b..74ecb36de74 100644 --- a/Master/texmf-dist/tex/context/base/lpdf-ini.lua +++ b/Master/texmf-dist/tex/context/base/lpdf-ini.lua @@ -9,33 +9,54 @@ if not modules then modules = { } end modules ['lpdf-ini'] = { local setmetatable, getmetatable, type, next, tostring, tonumber, rawset = setmetatable, getmetatable, type, next, tostring, tonumber, rawset local char, byte, format, gsub, concat, match, sub, gmatch = string.char, string.byte, string.format, string.gsub, table.concat, string.match, string.sub, string.gmatch local utfvalues = string.utfvalues -local texwrite, texset, texsprint, ctxcatcodes = tex.write, tex.set, tex.sprint, tex.ctxcatcodes +local texset = tex.set local sind, cosd = math.sind, math.cosd local lpegmatch = lpeg.match -local pdfreserveobj = pdf and pdf.reserveobj or function() return 1 end -- for testing -local pdfimmediateobj = pdf and pdf.immediateobj or function() return 2 end -- for testing +--~ local pdfreserveobject = pdf and pdf.reserveobj or function() return 1 end -- for testing +--~ local pdfimmediateobject = pdf and pdf.immediateobj or function() return 2 end -- for testing + +local pdfreserveobject = pdf.reserveobj +local pdfimmediateobject = pdf.immediateobj +local pdfdeferredobject = pdf.obj +local pdfreferenceobject = pdf.refobj local trace_finalizers = false trackers.register("backend.finalizers", function(v) trace_finalizers = v end) local trace_resources = false trackers.register("backend.resources", function(v) trace_resources = v end) local trace_objects = false trackers.register("backend.objects", function(v) trace_objects = v end) local trace_detail = false trackers.register("backend.detail", function(v) trace_detail = v end) -lpdf = lpdf or { } +local report_objects = logs.reporter("backend","objects") +local report_finalizing = logs.reporter("backend","finalizing") + +local backends, context = backends, context + +backends.pdf = backends.pdf or { + comment = "backend for directly generating pdf output", + nodeinjections = { }, + codeinjections = { }, + registrations = { }, + tables = { }, +} + +lpdf = lpdf or { } +local lpdf = lpdf local function tosixteen(str) if not str or str == "" then - return "()" + return "<feff>" -- not () as we want an indication that it's unicode else - local r = { "<feff" } + local r, n = { "<feff" }, 1 for b in utfvalues(str) do + n = n + 1 if b < 0x10000 then - r[#r+1] = format("%04x",b) + r[n] = format("%04x",b) else - r[#r+1] = format("%04x%04x",b/1024+0xD800,b%1024+0xDC00) + r[n] = format("%04x%04x",b/1024+0xD800,b%1024+0xDC00) end end - r[#r+1] = ">" + n = n + 1 + r[n] = ">" return concat(r) end end @@ -72,12 +93,12 @@ end lpdf.toeight = toeight ---~ local escaped = lpeg.Cs((lpeg.S("\0\t\n\r\f ()[]{}/%")/"#" + lpeg.P(1))^0) ---~ +--~ local escaped = lpeg.Cs((lpeg.S("\0\t\n\r\f ()[]{}/%")/function(s) return format("#%02X",byte(s)) end + lpeg.P(1))^0) + --~ local function cleaned(str) --~ return (str and str ~= "" and lpegmatch(escaped,str)) or "" --~ end ---~ + --~ lpdf.cleaned = cleaned -- not public yet local function merge_t(a,b) @@ -97,24 +118,25 @@ tostring_d = function(t,contentonly,key) return "<< >>" end else - local r = { } + local r, rn = { }, 0 for k, v in next, t do + rn = rn + 1 local tv = type(v) if tv == "string" then - r[#r+1] = format("/%s %s",k,toeight(v)) + r[rn] = format("/%s %s",k,toeight(v)) elseif tv == "unicode" then - r[#r+1] = format("/%s %s",k,tosixteen(v)) + r[rn] = format("/%s %s",k,tosixteen(v)) elseif tv == "table" then local mv = getmetatable(v) if mv and mv.__lpdftype then - r[#r+1] = format("/%s %s",k,tostring(v)) + r[rn] = format("/%s %s",k,tostring(v)) elseif v[1] then - r[#r+1] = format("/%s %s",k,tostring_a(v)) + r[rn] = format("/%s %s",k,tostring_a(v)) else - r[#r+1] = format("/%s %s",k,tostring_d(v)) + r[rn] = format("/%s %s",k,tostring_d(v)) end else - r[#r+1] = format("/%s %s",k,tostring(v)) + r[rn] = format("/%s %s",k,tostring(v)) end end if contentonly then @@ -128,7 +150,8 @@ tostring_d = function(t,contentonly,key) end tostring_a = function(t,contentonly,key) - if #t == 0 then + local tn = #t + if tn == 0 then if contentonly then return "" else @@ -136,24 +159,25 @@ tostring_a = function(t,contentonly,key) end else local r = { } - for k, v in next, t do + for k=1,tn do + local v = t[k] local tv = type(v) if tv == "string" then - r[#r+1] = toeight(v) + r[k] = toeight(v) elseif tv == "unicode" then - r[#r+1] = tosixteen(v) + r[k] = tosixteen(v) elseif tv == "table" then local mv = getmetatable(v) local mt = mv and mv.__lpdftype if mt then - r[#r+1] = tostring(v) + r[k] = tostring(v) elseif v[1] then - r[#r+1] = tostring_a(v) + r[k] = tostring_a(v) else - r[#r+1] = tostring_d(v) + r[k] = tostring_d(v) end else - r[#r+1] = tostring(v) + r[k] = tostring(v) end end if contentonly then @@ -174,7 +198,7 @@ local tostring_c = function(t) return t[1] end -- already prefixed (h local tostring_z = function() return "null" end local tostring_t = function() return "true" end local tostring_f = function() return "false" end -local tostring_r = function(t) return t[1] .. " 0 R" end +local tostring_r = function(t) local n = t[1] return n and n > 0 and (n .. " 0 R") or "NULL" end local tostring_v = function(t) local s = t[1] @@ -185,18 +209,18 @@ local tostring_v = function(t) end end -local function value_x(t) return t end -- the call is experimental -local function value_s(t,key) return t[1] end -- the call is experimental -local function value_u(t,key) return t[1] end -- the call is experimental -local function value_n(t,key) return t[1] end -- the call is experimental -local function value_c(t) return sub(t[1],2) end -- the call is experimental -local function value_d(t) return tostring_d(t,true,key) end -- the call is experimental -local function value_a(t) return tostring_a(t,true,key) end -- the call is experimental -local function value_z() return nil end -- the call is experimental -local function value_t(t) return t.value or true end -- the call is experimental -local function value_f(t) return t.value or false end -- the call is experimental -local function value_r() return t[1] end -- the call is experimental -local function value_v() return t[1] end -- the call is experimental +local function value_x(t) return t end -- the call is experimental +local function value_s(t,key) return t[1] end -- the call is experimental +local function value_u(t,key) return t[1] end -- the call is experimental +local function value_n(t,key) return t[1] end -- the call is experimental +local function value_c(t) return sub(t[1],2) end -- the call is experimental +local function value_d(t) return tostring_d(t,true) end -- the call is experimental +local function value_a(t) return tostring_a(t,true) end -- the call is experimental +local function value_z() return nil end -- the call is experimental +local function value_t(t) return t.value or true end -- the call is experimental +local function value_f(t) return t.value or false end -- the call is experimental +local function value_r() return t[1] or 0 end -- the call is experimental -- NULL +local function value_v() return t[1] end -- the call is experimental local function add_x(t,k,v) rawset(t,k,tostring(v)) end @@ -305,7 +329,7 @@ local function pdfverbose(t) -- maybe check for type return setmetatable({ t or "" },mt_v) end -lpdf.stream = pdfstream +lpdf.stream = pdfstream -- THIS WILL PROBABLY CHANGE lpdf.dictionary = pdfdictionary lpdf.array = pdfarray lpdf.string = pdfstring @@ -329,55 +353,91 @@ lpdf.verbose = pdfverbose local names, cache = { }, { } function lpdf.reserveobject(name) - local r = pdfreserveobj() - if name then - names[name] = r - if trace_objects then - logs.report("backends", "reserving object number %s under name '%s'",r,name) + if name == "annot" then + -- catch misuse + return pdfreserveobject("annot") + else + local r = pdfreserveobject() + if name then + names[name] = r + if trace_objects then + report_objects("reserving number %s under name '%s'",r,name) + end + elseif trace_objects then + report_objects("reserving number %s",r) end - elseif trace_objects then - logs.report("backends", "reserving object number %s",r) + return r end - return r end ---~ local pdfreserveobject = lpdf.reserveobject +function lpdf.reserveannotation() + return pdfreserveobject("annot") +end + +lpdf.immediateobject = pdfimmediateobject +lpdf.object = pdfdeferredobject -- the table interface, todo: auto attr() and so +lpdf.deferredobject = pdfdeferredobject +lpdf.referenceobject = pdfreferenceobject +lpdf.pagereference = pdf.pageref or tex.pdfpageref +lpdf.registerannotation = pdf.registerannot + +function lpdf.delayedobject(data) + local n = pdfdeferredobject(data) + pdfreferenceobject(n) + return n +end function lpdf.flushobject(name,data) if data then - name = names[name] or name - if name then - if trace_objects then - if trace_detail then - logs.report("backends", "flushing object data to reserved object with name '%s' -> %s",name,tostring(data)) - else - logs.report("backends", "flushing object data to reserved object with name '%s'",name) - end + local named = names[name] + if named then + if not trace_objects then + elseif trace_detail then + report_objects("flushing data to reserved object with name '%s' -> %s",name,tostring(data)) + else + report_objects("flushing data to reserved object with name '%s'",name) end - return pdfimmediateobj(name,tostring(data)) + return pdfimmediateobject(named,tostring(data)) else - if trace_objects then - if trace_detail then - logs.report("backends", "flushing object data to reserved object with number %s -> %s",name,tostring(data)) - else - logs.report("backends", "flushing object data to reserved object with number %s",name) - end + if not trace_objects then + elseif trace_detail then + report_objects("flushing data to reserved object with number %s -> %s",name,tostring(data)) + else + report_objects("flushing data to reserved object with number %s",name) end - return pdfimmediateobj(tostring(data)) + return pdfimmediateobject(name,tostring(data)) end else if trace_objects and trace_detail then - logs.report("backends", "flushing object data -> %s",tostring(name)) + report_objects("flushing data -> %s",tostring(name)) end - return pdfimmediateobj(tostring(name)) + return pdfimmediateobject(tostring(name)) + end +end + +local shareobjectcache, shareobjectreferencecache = { }, { } + +function lpdf.shareobject(content) + content = tostring(content) + local o = shareobjectcache[content] + if not o then + o = pdfimmediateobject(content) + shareobjectcache[content] = o end + return o end -function lpdf.sharedobj(content) - local r = cache[content] +function lpdf.shareobjectreference(content) + content = tostring(content) + local r = shareobjectreferencecache[content] if not r then - r = pdfreference(pdfimmediateobj(content)) - cache[content] = r + local o = shareobjectcache[content] + if not o then + o = pdfimmediateobject(content) + shareobjectcache[content] = o + end + r = pdfreference(o) + shareobjectreferencecache[content] = r end return r end @@ -445,53 +505,71 @@ local function resetpageproperties() pagesattributes = pdfdictionary() end +resetpageproperties() + local function setpageproperties() ---~ texset("global", "pdfpageresources", pageresources ()) ---~ texset("global", "pdfpageattr", pageattributes ()) ---~ texset("global", "pdfpagesattr", pagesattributes()) pdf.pageresources = pageresources () pdf.pageattributes = pageattributes () pdf.pagesattributes = pagesattributes() end -function lpdf.addtopageresources (k,v) pageresources [k] = v end -function lpdf.addtopageattributes (k,v) pageattributes [k] = v end -function lpdf.addtopagesattributes(k,v) pagesattributes[k] = v end +local function addtopageresources (k,v) pageresources [k] = v end +local function addtopageattributes (k,v) pageattributes [k] = v end +local function addtopagesattributes(k,v) pagesattributes[k] = v end -local function set(where,f,when,what) - when = when or 2 +lpdf.addtopageresources = addtopageresources +lpdf.addtopageattributes = addtopageattributes +lpdf.addtopagesattributes = addtopagesattributes + +local function set(where,what,f,when,comment) + if type(when) == "string" then + when, comment = 2, when + elseif not when then + when = 2 + end local w = where[when] - w[#w+1] = f + w[#w+1] = { f, comment } if trace_finalizers then - logs.report("backend","%s set: [%s,%s]",what,when,#w) + report_finalizing("%s set: [%s,%s]",what,when,#w) end end local function run(where,what) + if trace_finalizers then + report_finalizing("start backend: category=%s, n=%s",what,#where) + end for i=1,#where do local w = where[i] for j=1,#w do + local wj = w[j] if trace_finalizers then - logs.report("backend","%s finalizer: [%s,%s]",what,i,j) + report_finalizing("%s finalizer: [%s,%s] %s",what,i,j,wj[2] or "") end - w[j]() + wj[1]() end end + if trace_finalizers then + report_finalizing("stop finalizing") + end end -function lpdf.registerpagefinalizer(f,when) - set(pagefinalizers,f,when,"page") +local function registerpagefinalizer(f,when,comment) + set(pagefinalizers,"page",f,when,comment) end -function lpdf.registerdocumentfinalizer(f,when) - set(documentfinalizers,f,when,"document") +local function registerdocumentfinalizer(f,when,comment) + set(documentfinalizers,"document",f,when,comment) end +lpdf.registerpagefinalizer = registerpagefinalizer +lpdf.registerdocumentfinalizer = registerdocumentfinalizer + function lpdf.finalizepage() if not environment.initex then - resetpageproperties() + -- resetpageproperties() -- maybe better before run(pagefinalizers,"page") setpageproperties() + resetpageproperties() -- maybe better before end end @@ -499,63 +577,89 @@ function lpdf.finalizedocument() if not environment.initex then run(documentfinalizers,"document") function lpdf.finalizedocument() - logs.report("backend","serious error: the document is finalized multiple times") + report_finalizing("serious error: the document is finalized multiple times") function lpdf.finalizedocument() end end end end +backends.pdf.codeinjections.finalizepage = lpdf.finalizepage -- will go when we have hook + +--~ callbacks.register("finish_pdfpage", lpdf.finalizepage) +callbacks.register("finish_pdffile", lpdf.finalizedocument) + -- some minimal tracing, handy for checking the order local function trace_set(what,key) if trace_resources then - logs.report("backend", "setting key '%s' in '%s'",key,what) + report_finalizing("setting key '%s' in '%s'",key,what) end end local function trace_flush(what) if trace_resources then - logs.report("backend", "flushing '%s'",what) + report_finalizing("flushing '%s'",what) end end lpdf.protectresources = true -local catalog, info, names = pdfdictionary(), pdfdictionary(), pdfdictionary() +local catalog = pdfdictionary { Type = pdfconstant("Catalog") } -- nicer, but when we assign we nil the Type +local info = pdfdictionary { Type = pdfconstant("Info") } -- nicer, but when we assign we nil the Type +local names = pdfdictionary { Type = pdfconstant("Names") } -- nicer, but when we assign we nil the Type -local function flushcatalog() if not environment.initex then trace_flush("catalog") pdf.catalog = catalog() end end -local function flushinfo () if not environment.initex then trace_flush("info") pdf.info = info () end end -local function flushnames () if not environment.initex then trace_flush("names") pdf.names = names () end end +local function flushcatalog() if not environment.initex then trace_flush("catalog") catalog.Type = nil pdf.catalog = catalog() end end +local function flushinfo () if not environment.initex then trace_flush("info") info .Type = nil pdf.info = info () end end +local function flushnames () if not environment.initex then trace_flush("names") names .Type = nil pdf.names = names () end end function lpdf.addtocatalog(k,v) if not (lpdf.protectresources and catalog[k]) then trace_set("catalog",k) catalog[k] = v end end function lpdf.addtoinfo (k,v) if not (lpdf.protectresources and info [k]) then trace_set("info", k) info [k] = v end end function lpdf.addtonames (k,v) if not (lpdf.protectresources and names [k]) then trace_set("names", k) names [k] = v end end -local dummy = pdfreserveobj() -- else bug in hvmd due so some internal luatex conflict +local dummy = pdfreserveobject() -- else bug in hvmd due so some internal luatex conflict + +-- Some day I will implement a proper minimalized resource management. -local r_extgstates, d_extgstates = pdfreserveobj(), pdfdictionary() local p_extgstates = pdfreference(r_extgstates) -local r_colorspaces, d_colorspaces = pdfreserveobj(), pdfdictionary() local p_colorspaces = pdfreference(r_colorspaces) -local r_patterns, d_patterns = pdfreserveobj(), pdfdictionary() local p_patterns = pdfreference(r_patterns) -local r_shades, d_shades = pdfreserveobj(), pdfdictionary() local p_shades = pdfreference(r_shades) +local r_extgstates, d_extgstates = pdfreserveobject(), pdfdictionary() local p_extgstates = pdfreference(r_extgstates) +local r_colorspaces, d_colorspaces = pdfreserveobject(), pdfdictionary() local p_colorspaces = pdfreference(r_colorspaces) +local r_patterns, d_patterns = pdfreserveobject(), pdfdictionary() local p_patterns = pdfreference(r_patterns) +local r_shades, d_shades = pdfreserveobject(), pdfdictionary() local p_shades = pdfreference(r_shades) -local function checkextgstates () if next(d_extgstates ) then lpdf.addtopageresources("ExtGState", p_extgstates ) end end -local function checkcolorspaces() if next(d_colorspaces) then lpdf.addtopageresources("ColorSpace",p_colorspaces) end end -local function checkpatterns () if next(d_patterns ) then lpdf.addtopageresources("Pattern", p_patterns ) end end -local function checkshades () if next(d_shades ) then lpdf.addtopageresources("Shading", p_shades ) end end +local function checkextgstates () if next(d_extgstates ) then addtopageresources("ExtGState", p_extgstates ) end end +local function checkcolorspaces() if next(d_colorspaces) then addtopageresources("ColorSpace",p_colorspaces) end end +local function checkpatterns () if next(d_patterns ) then addtopageresources("Pattern", p_patterns ) end end +local function checkshades () if next(d_shades ) then addtopageresources("Shading", p_shades ) end end -local function flushextgstates () if next(d_extgstates ) then trace_flush("extgstates") pdfimmediateobj(r_extgstates, tostring(d_extgstates )) end end -local function flushcolorspaces() if next(d_colorspaces) then trace_flush("colorspaces") pdfimmediateobj(r_colorspaces,tostring(d_colorspaces)) end end -local function flushpatterns () if next(d_patterns ) then trace_flush("patterns") pdfimmediateobj(r_patterns, tostring(d_patterns )) end end -local function flushshades () if next(d_shades ) then trace_flush("shades") pdfimmediateobj(r_shades, tostring(d_shades )) end end +local function flushextgstates () if next(d_extgstates ) then trace_flush("extgstates") pdfimmediateobject(r_extgstates, tostring(d_extgstates )) end end +local function flushcolorspaces() if next(d_colorspaces) then trace_flush("colorspaces") pdfimmediateobject(r_colorspaces,tostring(d_colorspaces)) end end +local function flushpatterns () if next(d_patterns ) then trace_flush("patterns") pdfimmediateobject(r_patterns, tostring(d_patterns )) end end +local function flushshades () if next(d_shades ) then trace_flush("shades") pdfimmediateobject(r_shades, tostring(d_shades )) end end -local collected = pdfdictionary { - ExtGState = p_extgstates, - ColorSpace = p_colorspaces, - Pattern = p_patterns, - Shading = p_shades, -} ; collected = collected() +--~ local collected = pdfdictionary { +--~ ExtGState = p_extgstates, +--~ ColorSpace = p_colorspaces, +--~ Pattern = p_patterns, +--~ Shading = p_shades, +--~ } ; collected = collected() + +--~ function lpdf.collectedresources() +--~ context(collected) +--~ end function lpdf.collectedresources() - tex.sprint(tex.ctxcatcodes,collected) + local ExtGState = next(d_extgstates ) and p_extgstates + local ColorSpace = next(d_colorspaces) and p_colorspaces + local Pattern = next(d_patterns ) and p_patterns + local Shading = next(d_shades ) and p_shades + if ExtGState or ColorSpace or Pattern or Shading then + local collected = pdfdictionary { + ExtGState = ExtGState, + ColorSpace = ColorSpace, + Pattern = Pattern, + Shading = Shading, + -- ProcSet = pdfarray { pdfconstant("PDF") }, + } + context(collected()) + end end function lpdf.adddocumentextgstate (k,v) d_extgstates [k] = v end @@ -563,25 +667,25 @@ function lpdf.adddocumentcolorspace(k,v) d_colorspaces[k] = v end function lpdf.adddocumentpattern (k,v) d_patterns [k] = v end function lpdf.adddocumentshade (k,v) d_shades [k] = v end -lpdf.registerdocumentfinalizer(flushextgstates,3) -lpdf.registerdocumentfinalizer(flushcolorspaces,3) -lpdf.registerdocumentfinalizer(flushpatterns,3) -lpdf.registerdocumentfinalizer(flushshades,3) +registerdocumentfinalizer(flushextgstates,3,"extended graphic states") +registerdocumentfinalizer(flushcolorspaces,3,"color spaces") +registerdocumentfinalizer(flushpatterns,3,"patterns") +registerdocumentfinalizer(flushshades,3,"shades") -lpdf.registerdocumentfinalizer(flushcatalog,3) -lpdf.registerdocumentfinalizer(flushinfo,3) -lpdf.registerdocumentfinalizer(flushnames,3) +registerdocumentfinalizer(flushcatalog,3,"catalog") +registerdocumentfinalizer(flushinfo,3,"info") +registerdocumentfinalizer(flushnames,3,"names") -- before catalog -lpdf.registerpagefinalizer(checkextgstates,3) -lpdf.registerpagefinalizer(checkcolorspaces,3) -lpdf.registerpagefinalizer(checkpatterns,3) -lpdf.registerpagefinalizer(checkshades,3) +registerpagefinalizer(checkextgstates,3,"extended graphic states") +registerpagefinalizer(checkcolorspaces,3,"color spaces") +registerpagefinalizer(checkpatterns,3,"patterns") +registerpagefinalizer(checkshades,3,"shades") --- in strc-bkm: lpdf.registerdocumentfinalizer(function() structure.bookmarks.place() end,1) +-- in strc-bkm: lpdf.registerdocumentfinalizer(function() structures.bookmarks.place() end,1) function lpdf.rotationcm(a) local s, c = sind(a), cosd(a) - texwrite(format("%s %s %s %s 0 0 cm",c,s,-s,c)) + context("%s %s %s %s 0 0 cm",c,s,-s,c) end -- ! -> universaltime @@ -601,36 +705,36 @@ function lpdf.id() return format("%s.%s",tex.jobname,timestamp) end -function lpdf.checkedkey(t,key,kind) +function lpdf.checkedkey(t,key,variant) local pn = t[key] if pn then local tn = type(pn) - if tn == kind then - if kind == "string" then - return pn ~= "" and pn - elseif kind == "table" then - return next(pn) and pn + if tn == variant then + if variant == "string" then + return pn ~= "" and pn or nil + elseif variant == "table" then + return next(pn) and pn or nil else return pn end - elseif tn == "string" and kind == "number" then + elseif tn == "string" and variant == "number" then return tonumber(pn) end end end -function lpdf.checkedvalue(value,kind) -- code not shared +function lpdf.checkedvalue(value,variant) -- code not shared if value then local tv = type(value) - if tv == kind then - if kind == "string" then + if tv == variant then + if variant == "string" then return value ~= "" and value - elseif kind == "table" then + elseif variant == "table" then return next(value) and value else return value end - elseif tv == "string" and kind == "number" then + elseif tv == "string" and variant == "number" then return tonumber(value) end end @@ -658,13 +762,29 @@ end -- lpdf.addtoinfo("ConTeXt.Jobname", tex.jobname) -- lpdf.addtoinfo("ConTeXt.Url", "www.pragma-ade.com") --- saves definitions later on +if not pdfreferenceobject then -backends = backends or { } -backends.pdf = backends.pdf or { - comment = "backend for directly generating pdf output", - nodeinjections = { }, - codeinjections = { }, - registrations = { }, - helpers = { }, -} + local delayed = { } + + local function flush() + local n = 0 + for k,v in next, delayed do + pdfimmediateobject(k,v) + n = n + 1 + end + if trace_objects then + report_objects("%s objects flushed",n) + end + delayed = { } + end + + lpdf.registerdocumentfinalizer(flush,3,"objects") -- so we need a final flush too + lpdf.registerpagefinalizer (flush,3,"objects") -- somehow this lags behind .. I need to look into that some day + + function lpdf.delayedobject(data) + local n = pdfreserveobject() + delayed[n] = data + return n + end + +end |