summaryrefslogtreecommitdiff
path: root/tex/context/base/mkiv/lpdf-ano.lua
diff options
context:
space:
mode:
Diffstat (limited to 'tex/context/base/mkiv/lpdf-ano.lua')
-rw-r--r--tex/context/base/mkiv/lpdf-ano.lua188
1 files changed, 95 insertions, 93 deletions
diff --git a/tex/context/base/mkiv/lpdf-ano.lua b/tex/context/base/mkiv/lpdf-ano.lua
index 05f18f512..1c4a3ba27 100644
--- a/tex/context/base/mkiv/lpdf-ano.lua
+++ b/tex/context/base/mkiv/lpdf-ano.lua
@@ -133,6 +133,99 @@ local function checkautoprefixes(destinations)
end
end
+local maxslice = 32 -- could be made configureable ... 64 is also ok
+
+local function pdfmakenametree(list,apply)
+ if not next(list) then
+ return
+ end
+ local slices = { }
+ local sorted = sortedkeys(list)
+ local size = #sorted
+ local maxslice = maxslice
+ if size <= 1.5*maxslice then
+ maxslice = size
+ end
+ for i=1,size,maxslice do
+ local amount = min(i+maxslice-1,size)
+ local names = pdfarray { }
+ local n = 0
+ for j=i,amount do
+ local name = sorted[j]
+ local target = list[name]
+ n = n + 1 ; names[n] = tostring(name)
+ n = n + 1 ; names[n] = apply and apply(target) or target
+ end
+ local first = sorted[i]
+ local last = sorted[amount]
+ local limits = pdfarray {
+ first,
+ last,
+ }
+ local d = pdfdictionary {
+ Names = names,
+ Limits = limits,
+ }
+ slices[#slices+1] = {
+ reference = pdfreference(pdfflushobject(d)),
+ limits = limits,
+ }
+ end
+ local function collectkids(slices,first,last)
+ local f = slices[first]
+ local l = slices[last]
+ if f and l then
+ local k = pdfarray()
+ local n = 0
+ local d = pdfdictionary {
+ Kids = k,
+ Limits = pdfarray {
+ f.limits[1],
+ l.limits[2],
+ },
+ }
+ for i=first,last do
+ n = n + 1 ; k[n] = slices[i].reference
+ end
+ return d
+ end
+ end
+ if #slices == 1 then
+ return slices[1].reference
+ else
+ while true do
+ local size = #slices
+ if size > maxslice then
+ local temp = { }
+ local n = 0
+ for i=1,size,maxslice do
+ local kids = collectkids(slices,i,min(i+maxslice-1,size))
+ if kids then
+ n = n + 1
+ temp[n] = {
+ reference = pdfreference(pdfflushobject(kids)),
+ limits = kids.Limits,
+ }
+ else
+ -- error
+ end
+ end
+ slices = temp
+ else
+ local kids = collectkids(slices,1,size)
+ if kids then
+ return pdfreference(pdfflushobject(kids))
+ else
+ -- error
+ return
+ end
+ end
+ end
+ end
+end
+
+lpdf.makenametree = pdfmakenametree
+
-- Bah, I hate this kind of features .. anyway, as we have delayed resolving we
-- only support a document-wide setup and it has to be set before the first one
-- is used. Also, we default to a non-intrusive gray and the outline is kept
@@ -237,8 +330,6 @@ end
lpdf.registerdestination = pdfregisterdestination
-local maxslice = 32 -- could be made configureable ... 64 is also ok
-
logs.registerfinalactions(function()
if log_destinations and next(destinations) then
local report = logs.startfilelogging("references","used destinations")
@@ -252,98 +343,10 @@ logs.registerfinalactions(function()
end
end)
-local function pdfnametree(destinations)
- local slices = { }
- checkautoprefixes(destinations)
- if not next(destinations) then
- return
- end
- local sorted = sortedkeys(destinations)
- local size = #sorted
-
- if size <= 1.5*maxslice then
- maxslice = size
- end
-
- for i=1,size,maxslice do
- local amount = min(i+maxslice-1,size)
- local names = pdfarray { }
- local n = 0
- for j=i,amount do
- local destination = sorted[j]
- local pagenumber = destinations[destination]
- n = n + 1 ; names[n] = tostring(destination) -- tostring is a safeguard
- n = n + 1 ; names[n] = pdfreference(pagenumber)
- end
- local first = sorted[i]
- local last = sorted[amount]
- local limits = pdfarray {
- first,
- last,
- }
- local d = pdfdictionary {
- Names = names,
- Limits = limits,
- }
- slices[#slices+1] = {
- reference = pdfreference(pdfflushobject(d)),
- limits = limits,
- }
- end
- local function collectkids(slices,first,last)
- local f = slices[first]
- local l = slices[last]
- if f and l then
- local k = pdfarray()
- local n = 0
- local d = pdfdictionary {
- Kids = k,
- Limits = pdfarray {
- f.limits[1],
- l.limits[2],
- },
- }
- for i=first,last do
- n = n + 1 ; k[n] = slices[i].reference
- end
- return d
- end
- end
- if #slices == 1 then
- return slices[1].reference
- else
- while true do
- if #slices > maxslice then
- local temp = { }
- local size = #slices
- for i=1,size,maxslice do
- local kids = collectkids(slices,i,min(i+maxslice-1,size))
- if kids then
- temp[#temp+1] = {
- reference = pdfreference(pdfflushobject(kids)),
- limits = kids.Limits,
- }
- else
- -- error
- end
- end
- slices = temp
- else
- local kids = collectkids(slices,1,#slices)
- if kids then
- return pdfreference(pdfflushobject(kids))
- else
- -- error
- return
- end
- end
- end
- end
-end
-
local function pdfdestinationspecification()
if next(destinations) then -- safeguard
- local r = pdfnametree(destinations)
+ checkautoprefixes(destinations)
+ local r = pdfmakenametree(destinations,pdfreference)
if r then
pdfaddtonames("Dests",r)
end
@@ -353,7 +356,6 @@ local function pdfdestinationspecification()
end
end
-lpdf.nametree = pdfnametree
lpdf.destinationspecification = pdfdestinationspecification
lpdf.registerdocumentfinalizer(pdfdestinationspecification,"collect destinations")