summaryrefslogtreecommitdiff
path: root/tex/context/base/mkiv/lpdf-lmt.lua
diff options
context:
space:
mode:
Diffstat (limited to 'tex/context/base/mkiv/lpdf-lmt.lua')
-rw-r--r--tex/context/base/mkiv/lpdf-lmt.lua357
1 files changed, 201 insertions, 156 deletions
diff --git a/tex/context/base/mkiv/lpdf-lmt.lua b/tex/context/base/mkiv/lpdf-lmt.lua
index 4cce7fc74..e79a5a17f 100644
--- a/tex/context/base/mkiv/lpdf-lmt.lua
+++ b/tex/context/base/mkiv/lpdf-lmt.lua
@@ -843,15 +843,10 @@ end
-- rules
-local f_font = formatters["F%d"]
-local f_form = formatters["Fm%d"]
-local f_group = formatters["Gp%d"]
-local f_image = formatters["Im%d"]
+local flushedxforms = { } -- actually box resources but can also be direct
+local localconverter = nil -- will be set
-local flushedxforms = { } -- actually box resources but can also be direct
-local localconverter = nil -- will be set
-
-local flushrule, flushsimplerule, flushimage do
+local flushrule, flushsimplerule, flushimage, flushgroup do
local rulecodes = nodes.rulecodes
local newrule = nodes.pool.rule
@@ -874,6 +869,7 @@ local flushrule, flushsimplerule, flushimage do
local f_fm = formatters["/Fm%d Do"]
local f_im = formatters["/Im%d Do"]
+ local f_gr = formatters["/Gp%d Do"]
local s_b <const> = "q"
local s_e <const> = "Q"
@@ -1054,7 +1050,7 @@ local flushrule, flushsimplerule, flushimage do
local groups = 0
local group = nil
- function lpdf.flushgroup(content,bbox)
+ flushgroup = function(content,bbox)
if not group then
group = pdfdictionary {
Type = pdfconstant("Group"),
@@ -1072,9 +1068,11 @@ local flushrule, flushsimplerule, flushimage do
local objnum = pdfflushstreamobject(content,wrapper,false)
groups = groups + 1
usedxgroups[groups] = objnum
- return f_group(groups)
+ return f_gr(groups)
end
+ lpdf.flushgroup = flushgroup -- todo: access via driver in mlib-pps
+
-- end of experiment
local function flushpdfximage(current,pos_h,pos_v,pos_r,size_h,size_v)
@@ -1310,16 +1308,61 @@ local wrapup, registerpage do
local pages = { }
local maxkids = 10
local nofpages = 0
+ local pagetag = "unset"
registerpage = function(object)
nofpages = nofpages + 1
local objnum = pdfpagereference(nofpages)
pages[nofpages] = {
+ page = nofpages, -- original number, only for diagnostics
objnum = objnum,
object = object,
+ tag = pagetag,
}
end
+ function lpdf.setpagetag(tag)
+ pagetag = tag or "unset"
+ end
+
+ function lpdf.getnofpages()
+ return nofpages
+ end
+
+ function lpdf.getpagetags()
+ local list = { }
+ for i=1,nofpages do
+ list[i] = pages[i].tag
+ end
+ return list
+ end
+
+ function lpdf.setpageorder(mapping)
+ -- mapping can be a hash so:
+ local list = table.sortedkeys(mapping)
+ local n = #list
+ if n == nofpages then
+ local done = { }
+ local hash = { }
+ for i=1,n do
+ local order = mapping[list[i]]
+ if hash[order] then
+ report("invalid page order, duplicate entry %i",order)
+ return
+ elseif order < 1 or order > nofpages then
+ report("invalid page order, no page %i",order)
+ return
+ else
+ done[i] = pages[order]
+ hash[order] = true
+ end
+ end
+ pages = done
+ else
+ report("invalid page order, %i entries expected",nofpages)
+ end
+ end
+
wrapup = function(driver)
-- hook (to reshuffle pages)
@@ -1467,176 +1510,191 @@ do
end
-local pushmode, popmode
+local flushdeferred -- defined later
-local function finalize(driver,details)
+local level = 0
- pushmode()
+local finalize do
- pdf_goto_pagemode() -- for now
+ local f_font = formatters["F%d"]
- local objnum = details.objnum
- local specification = details.specification
+ local f_form = formatters["Fm%d"]
+ local f_group = formatters["Gp%d"]
+ local f_image = formatters["Im%d"]
- local content = concat(buffer,"\n",1,b)
+ finalize = function(driver,details)
- if compact then
- content = compact(content)
- end
+ level = level + 1
- local fonts = nil
- local xforms = nil
+ pdf_goto_pagemode() -- for now
- if next(usedfonts) then
- fonts = pdfdictionary { }
- for k, v in next, usedfonts do
- fonts[f_font(v)] = pdfreference(pdfgetfontobjnumber(k)) -- we can overload for testing
- end
- end
+ local objnum = details.objnum
+ local specification = details.specification
- -- messy: use real indexes for both ... so we need to change some in the
- -- full luatex part
+ local content = concat(buffer,"\n",1,b)
- if next(usedxforms) or next(usedximages) or next(usedxgroups) then
- xforms = pdfdictionary { }
- for k in sortedhash(usedxforms) do
- -- xforms[f_form(k)] = pdfreference(k)
- xforms[f_form(getxformname(k))] = pdfreference(k)
+ if compact then
+ content = compact(content)
end
- for k, v in sortedhash(usedximages) do
- xforms[f_image(k)] = pdfreference(v)
- end
- for k, v in sortedhash(usedxgroups) do
- xforms[f_group(k)] = pdfreference(v)
+
+ local fonts = nil
+ local xforms = nil
+
+ if next(usedfonts) then
+ fonts = pdfdictionary { }
+ for k, v in next, usedfonts do
+ fonts[f_font(v)] = pdfreference(pdfgetfontobjnumber(k)) -- we can overload for testing
+ end
end
- end
- reset_buffer()
+ -- messy: use real indexes for both ... so we need to change some in the
+ -- full luatex part
- -- finish_pdfpage_callback(shippingmode == "page")
+ if next(usedxforms) or next(usedximages) or next(usedxgroups) then
+ xforms = pdfdictionary { }
+ for k in sortedhash(usedxforms) do
+ -- xforms[f_form(k)] = pdfreference(k)
+ xforms[f_form(getxformname(k))] = pdfreference(k)
+ end
+ for k, v in sortedhash(usedximages) do
+ xforms[f_image(k)] = pdfreference(v)
+ end
+ for k, v in sortedhash(usedxgroups) do
+ xforms[f_group(k)] = pdfreference(v)
+ end
+ end
- if shippingmode == "page" then
+ reset_buffer()
- local pageproperties = lpdf.getpageproperties()
+ -- finish_pdfpage_callback(shippingmode == "page")
- local pageresources = pageproperties.pageresources
- local pageattributes = pageproperties.pageattributes
- local pagesattributes = pageproperties.pagesattributes
+ if shippingmode == "page" then
- pageresources.Font = fonts
- pageresources.XObject = xforms
- pageresources.ProcSet = lpdf.procset()
+ local pageproperties = lpdf.getpageproperties()
- local xorigin, yorigin, relocated = backends.codeinjections.getpageorigin() -- for now here
+ local pageresources = pageproperties.pageresources
+ local pageattributes = pageproperties.pageattributes
+ local pagesattributes = pageproperties.pagesattributes
- local bbox = pdfarray {
- (boundingbox[1] + xorigin) * bpfactor,
- (boundingbox[2] + yorigin) * bpfactor,
- (boundingbox[3] + xorigin) * bpfactor,
- (boundingbox[4] + yorigin) * bpfactor,
- }
+ pageresources.Font = fonts
+ pageresources.XObject = xforms
+ pageresources.ProcSet = lpdf.procset()
- if relocated then
- content = formatters["1 0 0 1 %.6N %.6N cm\n%s"](bbox[1],bbox[2],content)
- end
+ local xorigin, yorigin, relocated = backends.codeinjections.getpageorigin() -- for now here
- local contentsobj = pdfflushstreamobject(content,false,false)
+ local bbox = pdfarray {
+ (boundingbox[1] + xorigin) * bpfactor,
+ (boundingbox[2] + yorigin) * bpfactor,
+ (boundingbox[3] + xorigin) * bpfactor,
+ (boundingbox[4] + yorigin) * bpfactor,
+ }
- pageattributes.Type = pdf_page
- pageattributes.Contents = pdfreference(contentsobj)
- pageattributes.Resources = pageresources
- -- pageattributes.Resources = pdfreference(pdfflushobject(pageresources))
- pageattributes.MediaBox = bbox
- pageattributes.Parent = nil -- precalculate
- pageattributes.Group = nil -- todo
+ if relocated then
+ content = formatters["1 0 0 1 %.6N %.6N cm\n%s"](bbox[1],bbox[2],content)
+ end
- -- resources can be indirect
+ local contentsobj = pdfflushstreamobject(content,false,false)
- registerpage(pageattributes)
+ pageattributes.Type = pdf_page
+ pageattributes.Contents = pdfreference(contentsobj)
+ pageattributes.Resources = pageresources
+ -- pageattributes.Resources = pdfreference(pdfflushobject(pageresources))
+ pageattributes.MediaBox = bbox
+ pageattributes.Parent = nil -- precalculate
+ pageattributes.Group = nil -- todo
- lpdf.finalizepage(true)
+ -- resources can be indirect
- if relocated then
- if pageattributes.TrimBox then pageattributes.TrimBox = box end
- if pageattributes.CropBox then pageattributes.CropBox = box end
- if pageattributes.BleedBox then pageattributes.BleedBox = box end
- end
+ registerpage(pageattributes)
- else
+ lpdf.finalizepage(true)
+
+ if relocated then
+ if pageattributes.TrimBox then pageattributes.TrimBox = box end
+ if pageattributes.CropBox then pageattributes.CropBox = box end
+ if pageattributes.BleedBox then pageattributes.BleedBox = box end
+ end
- local xformtype = specification.type or 0
- local margin = specification.margin or 0
- local attributes = specification.attributes or ""
- local resources = specification.resources or ""
-
- local wrapper = nil
-
- if xformtype == 0 then
- wrapper = pdfdictionary {
- Type = pdf_xobject,
- Subtype = pdf_form,
- FormType = 1,
- BBox = nil,
- Matrix = nil,
- Resources = nil,
- }
else
- wrapper = pdfdictionary {
- BBox = nil,
- Matrix = nil,
- Resources = nil,
- }
- end
- if xformtype == 0 or xformtype == 1 or xformtype == 3 then
- wrapper.BBox = pdfarray {
- -margin * bpfactor,
- -margin * bpfactor,
- (boundingbox[3] + margin) * bpfactor,
- (boundingbox[4] + margin) * bpfactor,
- }
- end
- if xformtype == 0 or xformtype == 2 or xformtype == 3 then
- wrapper.Matrix = pdfarray { 1, 0, 0, 1, 0, 0 }
- end
- -- todo: additional = resources
+ local xformtype = specification.type or 0
+ local margin = specification.margin or 0
+ local attributes = specification.attributes or ""
+ local resources = specification.resources or ""
+
+ local wrapper = nil
+
+ if xformtype == 0 then
+ wrapper = pdfdictionary {
+ Type = pdf_xobject,
+ Subtype = pdf_form,
+ FormType = 1,
+ BBox = nil,
+ Matrix = nil,
+ Resources = nil,
+ }
+ else
+ wrapper = pdfdictionary {
+ BBox = nil,
+ Matrix = nil,
+ Resources = nil,
+ }
+ end
+ if xformtype == 0 or xformtype == 1 or xformtype == 3 then
+ wrapper.BBox = pdfarray {
+ -margin * bpfactor,
+ -margin * bpfactor,
+ (boundingbox[3] + margin) * bpfactor,
+ (boundingbox[4] + margin) * bpfactor,
+ }
+ end
+ if xformtype == 0 or xformtype == 2 or xformtype == 3 then
+ wrapper.Matrix = pdfarray { 1, 0, 0, 1, 0, 0 }
+ end
- local boxresources = lpdf.collectedresources { serialize = false }
- boxresources.Font = fonts
- boxresources.XObject = xforms
+ -- todo: additional = resources
- -- todo: maybe share them
- -- wrapper.Resources = pdfreference(pdfflushobject(boxresources))
+ local boxresources = lpdf.collectedresources { serialize = false }
+ boxresources.Font = fonts
+ boxresources.XObject = xforms
- if resources ~= "" then
- boxresources = boxresources + resources
- end
- if attributes ~= "" then
- wrapper = wrapper + attributes
- end
+ -- todo: maybe share them
+ -- wrapper.Resources = pdfreference(pdfflushobject(boxresources))
- wrapper.Resources = next(boxresources) and boxresources or nil
- wrapper.ProcSet = lpdf.procset()
+ if resources ~= "" then
+ boxresources = boxresources + resources
+ end
+ if attributes ~= "" then
+ wrapper = wrapper + attributes
+ end
- -- pdfflushstreamobject(content,wrapper,false,objectnumber)
- pdfflushstreamobject(content,wrapper,false,specification.objnum)
+ wrapper.Resources = next(boxresources) and boxresources or nil
+ wrapper.ProcSet = lpdf.procset()
- end
+ -- pdfflushstreamobject(content,wrapper,false,objectnumber)
+ pdfflushstreamobject(content,wrapper,false,specification.objnum)
- for objnum in sortedhash(usedxforms) do
- local f = flushedxforms[objnum]
- if f[1] == false then
- f[1] = true
- local objnum = f[2] -- specification.objnum
- local specification = boxresources[objnum]
- local list = specification.list
- localconverter(list,"xform",f[2],specification)
end
- end
- pdf_h, pdf_v = 0, 0
+ for objnum in sortedhash(usedxforms) do
+ local f = flushedxforms[objnum]
+ if f[1] == false then
+ f[1] = true
+ local objnum = f[2] -- specification.objnum
+ local specification = boxresources[objnum]
+ local list = specification.list
+ localconverter(list,"xform",f[2],specification)
+ end
+ end
- popmode()
+ pdf_h, pdf_v = 0, 0
+
+ if level == 1 then
+ flushdeferred()
+ end
+ level = level - 1
+
+ end
end
@@ -1674,7 +1732,6 @@ local compress = true
local cache = false
local info = ""
local catalog = ""
-local level = 0
local lastdeferred = false
local majorversion = 1
local minorversion = 7
@@ -1687,14 +1744,14 @@ local f_stream_d_u = formatters["%i 0 obj\010<< %s /Length %i >>\010stream\010
local f_stream_d_c = formatters["%i 0 obj\010<< %s /Filter /FlateDecode /Length %i >>\010stream\010%s\010endstream\010endobj\010"]
local f_stream_d_r = formatters["%i 0 obj\010<< %s >>\010stream\010%s\010endstream\010endobj\010"]
-local f_object_b = formatters["%i 0 obj\010"]
+----- f_object_b = formatters["%i 0 obj\010"]
local f_stream_b_n_u = formatters["%i 0 obj\010<< /Length %i >>\010stream\010"]
local f_stream_b_n_c = formatters["%i 0 obj\010<< /Filter /FlateDecode /Length %i >>\010stream\010"]
local f_stream_b_d_u = formatters["%i 0 obj\010<< %s /Length %i >>\010stream\010"]
local f_stream_b_d_c = formatters["%i 0 obj\010<< %s /Filter /FlateDecode /Length %i >>\010stream\010"]
local f_stream_b_d_r = formatters["%i 0 obj\010<< %s >>\010stream\010"]
-local s_object_e <const> = "\010endobj\010"
+----- s_object_e <const> = "\010endobj\010"
local s_stream_e <const> = "\010endstream\010endobj\010"
do
@@ -1920,7 +1977,7 @@ local function flushstreamobj(data,n,dict,comp,nolength)
return n
end
-local function flushdeferred()
+flushdeferred = function() -- was forward defined
if lastdeferred then
for n=lastdeferred,nofobjects do
local o = objects[n]
@@ -1934,19 +1991,6 @@ local function flushdeferred()
end
end
--- These are already used above, so we define them now:
-
-pushmode = function()
- level = level + 1
-end
-
-popmode = function()
- if level == 1 then
- flushdeferred()
- end
- level = level - 1
-end
-
-- n = pdf.obj([n,] objtext)
-- n = pdf.obj([n,] "file", filename)
-- n = pdf.obj([n,] "stream", streamtext [, attrtext])
@@ -2659,6 +2703,7 @@ do
save = flushsave,
restore = flushrestore,
image = flushimage,
+ group = flushgroup,
--
updatefontstate = updatefontstate,
},