summaryrefslogtreecommitdiff
path: root/tex/context/base/mkiv/lpdf-ini.lua
diff options
context:
space:
mode:
authorHans Hagen <pragma@wxs.nl>2018-11-18 16:12:36 +0100
committerContext Git Mirror Bot <phg@phi-gamma.net>2018-11-18 16:12:36 +0100
commit744095aa4676553437db0d71c281a74557a3222f (patch)
treebfdf5d203b5fbfa44ee7db705d3b3475361ad28f /tex/context/base/mkiv/lpdf-ini.lua
parente2ee706a3114129601a30908d6b8cbb57068d32c (diff)
downloadcontext-744095aa4676553437db0d71c281a74557a3222f.tar.gz
2018-11-18 14:16:00
Diffstat (limited to 'tex/context/base/mkiv/lpdf-ini.lua')
-rw-r--r--tex/context/base/mkiv/lpdf-ini.lua805
1 files changed, 466 insertions, 339 deletions
diff --git a/tex/context/base/mkiv/lpdf-ini.lua b/tex/context/base/mkiv/lpdf-ini.lua
index f19245f06..a6702cd35 100644
--- a/tex/context/base/mkiv/lpdf-ini.lua
+++ b/tex/context/base/mkiv/lpdf-ini.lua
@@ -32,65 +32,61 @@ local context = context
-- encoded utf16 string type between <>. We could probably save some bytes by using
-- strings between () but then we end up with escaped ()\ too.
--- gethpos : used
--- getpos : used
--- getvpos : used
---
--- getmatrix : used
--- hasmatrix : used
---
--- mapfile : used in font-ctx.lua
--- mapline : used in font-ctx.lua
---
--- maxobjnum : not used
--- obj : used
--- immediateobj : used
--- objtype : not used
--- pageref : used
--- print : can be used
--- refobj : used
--- registerannot : not to be used
--- reserveobj : used
-
--- pdf.catalog : used
--- pdf.info : used
--- pdf.trailer : used
--- pdf.names : not to be used
-
--- pdf.setinfo : used
--- pdf.setcatalog : used
--- pdf.setnames : not to be used
--- pdf.settrailer : used
-
--- pdf.getinfo : used
--- pdf.getcatalog : used
--- pdf.getnames : not to be used
--- pdf.gettrailer : used
-
-local pdf = pdf
-local factor = number.dimenfactors.bp
-
-local pdfsetinfo = pdf.setinfo
-local pdfsetcatalog = pdf.setcatalog
------ pdfsettrailerid = pdf.settrailerid
------ pdfsetnames = pdf.setnames
------ pdfsettrailer = pdf.settrailer
-
-local pdfsetpageresources = pdf.setpageresources
-local pdfsetpageattributes = pdf.setpageattributes
-local pdfsetpagesattributes = pdf.setpagesattributes
-
-local pdfgetpos = pdf.getpos
-local pdfgethpos = pdf.gethpos
-local pdfgetvpos = pdf.getvpos
-local pdfgetmatrix = pdf.getmatrix
-local pdfhasmatrix = pdf.hasmatrix
-local pdfprint = pdf.print
-
-local pdfreserveobject = pdf.reserveobj
-local pdfimmediateobject = pdf.immediateobj
-local pdfdeferredobject = pdf.obj
-local pdfreferenceobject = pdf.refobj
+local pdf = pdf
+local factor = number.dimenfactors.bp
+
+local codeinjections = { }
+local nodeinjections = { }
+
+local backends = backends
+
+local pdfbackend = {
+ comment = "backend for directly generating pdf output",
+ nodeinjections = nodeinjections,
+ codeinjections = codeinjections,
+ registrations = { },
+ tables = { },
+}
+
+backends.pdf = pdfbackend
+
+lpdf = lpdf or { }
+local lpdf = lpdf
+lpdf.flags = lpdf.flags or { } -- will be filled later
+
+local pdfsetinfo = pdf.setinfo
+local pdfsetcatalog = pdf.setcatalog
+----- pdfsetnames = pdf.setnames
+----- pdfsettrailer = pdf.settrailer
+local pdfsettrailerid = pdf.settrailerid
+----- pdfsetomitcidset = pdf.setomitcidset
+
+local pdfsetpageresources = pdf.setpageresources
+local pdfsetpageattributes = pdf.setpageattributes
+local pdfsetpagesattributes = pdf.setpagesattributes
+
+local pdfreserveobject = pdf.reserveobj
+local pdfimmediateobject = pdf.immediateobj
+local pdfdeferredobject = pdf.obj
+local pdfreferenceobject = pdf.refobj
+
+local pdfgetfontname = pdf.getfontname
+local pdfgetfontobjnum = pdf.getfontobjnum
+local pdfgetxformname = pdf.getxformname
+local pdfincludeimage = pdf.includeimage
+local pdfincludechar = pdf.includechar
+local pdfgetpagereference = pdf.getpageref or pdf.pageref -- tex.pdfpageref is obsolete
+local pdfsetfontattributes = pdf.setfontattributes
+
+local setmajorversion = pdf.setmajorversion
+local setminorversion = pdf.setminorversion
+local getmajorversion = pdf.getmajorversion
+local getminorversion = pdf.getminorversion
+
+local setcompresslevel = pdf.setcompresslevel
+local setobjectcompresslevel = pdf.setobjcompresslevel
+local getcompresslevel = pdf.getcompresslevel
+local getobjectcompresslevel = pdf.getobjcompresslevel
local function pdfdisablecommand(command)
pdf[command] = function() report_blocked("'pdf.%s' is not supported",command) end
@@ -100,175 +96,206 @@ pdfdisablecommand("setinfo")
pdfdisablecommand("setcatalog")
pdfdisablecommand("setnames")
pdfdisablecommand("settrailer")
+pdfdisablecommand("settrailerid")
+pdfdisablecommand("setomitcidset")
pdfdisablecommand("setpageresources")
pdfdisablecommand("setpageattributes")
pdfdisablecommand("setpagesattributes")
pdfdisablecommand("registerannot")
+pdfdisablecommand("reserveobj")
pdf.disablecommand = pdfdisablecommand
+updaters.register("backend.update.lpdf",function()
+
+ pdfsetinfo = pdf.setinfo
+ pdfsetcatalog = pdf.setcatalog
+ pdfsettrailerid = pdf.settrailerid
+
+ pdfreserveobject = pdf.reserveobj
+ pdfimmediateobject = pdf.immediateobj
+ pdfdeferredobject = pdf.obj
+ pdfreferenceobject = pdf.refobj
+ pdfsetfontattributes = pdf.setfontattributes
+
+ pdfgetfontname = pdf.getfontname
+ pdfgetfontobjnum = pdf.getfontobjnum
+ pdfgetxformname = pdf.getxformname
+ pdfincludeimage = pdf.includeimage
+ pdfincludechar = pdf.includechar
+ pdfgetpagereference = pdf.getpageref
+
+
+ setmajorversion = pdf.setmajorversion
+ setminorversion = pdf.setminorversion
+ getmajorversion = pdf.getmajorversion
+ getminorversion = pdf.getminorversion
+
+ setcompresslevel = pdf.setcompresslevel
+ setobjectcompresslevel = pdf.setobjcompresslevel
+ getcompresslevel = pdf.getcompresslevel
+ getobjectcompresslevel = pdf.getobjcompresslevel
+
+ pdfdisablecommand("setinfo")
+ pdfdisablecommand("setcatalog")
+ pdfdisablecommand("settrailerid")
+
+ pdfdisablecommand("reserveobj")
+ pdfdisablecommand("getfontname")
+ pdfdisablecommand("getfontobjnum")
+end)
+
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)
-local backends = backends
-local pdfbackend = {
- comment = "backend for directly generating pdf output",
- nodeinjections = { },
- codeinjections = { },
- registrations = { },
- tables = { },
-}
-backends.pdf = pdfbackend
-lpdf = lpdf or { }
-local lpdf = lpdf
-
-lpdf.flags = lpdf.flags or { } -- will be filled later
+function lpdf.settrailerid(id)
+ pdfsettrailerid(id)
+end
-do
+function lpdf.setversion(major,minor)
+ setmajorversion(major or 1)
+ setminorversion(minor or 7)
+end
- local setmajorversion = pdf.setmajorversion
- local setminorversion = pdf.setminorversion
- local getmajorversion = pdf.getmajorversion
- local getminorversion = pdf.getminorversion
+function lpdf.getversion(major,minor)
+ return getmajorversion(), getminorversion()
+end
- if not setmajorversion then
+function lpdf.majorversion() return getmajorversion() end
+function lpdf.minorversion() return getminorversion() end
- setmajorversion = function() end
- getmajorversion = function() return 1 end
+function lpdf.getfontname (id) return pdfgetfontname (id) end
+function lpdf.getfontobjnumber(id) return pdfgetfontobjnum(id) end
- pdf.setmajorversion = setmajorversion
- pdf.getmajorversion = getmajorversion
+function lpdf.getxformname(id) return pdfgetxformname(id) end
+function lpdf.includeimage(id) return pdfincludeimage(id) end
- end
+function lpdf.includechar (f,c) pdfincludechar(f,c) end
+function lpdf.includecharlist(f,c) pdfincludechar(f,c) end -- can be disabled
- function lpdf.setversion(major,minor)
- setmajorversion(major or 1)
- setminorversion(minor or 7)
- end
+local frozen = false
- function lpdf.getversion(major,minor)
- return getmajorversion(), getminorversion()
+function lpdf.setcompression(level,objectlevel,freeze)
+ if not frozen then
+ setcompresslevel(level or 3)
+ setobjectcompresslevel(objectlevel or level or 3)
+ frozen = freeze
end
+end
- lpdf.majorversion = getmajorversion
- lpdf.minorversion = getminorversion
-
+function lpdf.getcompression()
+ return getcompresslevel(), getobjectcompresslevel()
end
-do
+function lpdf.compresslevel () return getcompresslevel () end
+function lpdf.objectcompresslevel() return getobjectcompresslevel() end
- local setcompresslevel = pdf.setcompresslevel
- local setobjectcompresslevel = pdf.setobjcompresslevel
- local getcompresslevel = pdf.getcompresslevel
- local getobjectcompresslevel = pdf.getobjcompresslevel
+do
- local frozen = false
+ local pdfgetpos = pdf.getpos
+ local pdfgethpos = pdf.gethpos
+ local pdfgetvpos = pdf.getvpos
+ local pdfgetmatrix = pdf.getmatrix
+ local pdfhasmatrix = pdf.hasmatrix
+ local pdfprint = pdf.print
- function lpdf.setcompression(level,objectlevel,freeze)
- if not frozen then
- setcompresslevel(level or 3)
- setobjectcompresslevel(objectlevel or level or 3)
- frozen = freeze
- end
+ function lpdf.getpos()
+ return pdfgetpos()
end
- function lpdf.getcompression()
- return getcompresslevel(), getobjectcompresslevel()
+ function lpdf.gethpos()
+ return pdfgethpos()
end
- lpdf.compresslevel = getcompresslevel
- lpdf.objectcompresslevel = getobjectcompresslevel
-
-end
+ function lpdf.getvpos()
+ return pdfgetvpos()
+ end
-local codeinjections = pdfbackend.codeinjections
-local nodeinjections = pdfbackend.nodeinjections
+ pdfbackend.codeinjections.getpos = lpdf.getpos
+ pdfbackend.codeinjections.gethpos = lpdf.gethpos
+ pdfbackend.codeinjections.getvpos = lpdf.getvpos
--- can change:
+ updaters.register("backend.update.lpdf",function()
+ pdfgetpos = pdf.getpos
+ pdfgethpos = pdf.gethpos
+ pdfgetvpos = pdf.getvpos
+ end)
-pdfbackend.codeinjections.getpos = pdfgetpos
-pdfbackend.codeinjections.gethpos = pdfgethpos
-pdfbackend.codeinjections.getvpos = pdfgetvpos
+ -- todo
-lpdf.getpos = pdfgetpos
-lpdf.gethpos = pdfgethpos
-lpdf.getvpos = pdfgetvpos
-lpdf.print = pdfprint
+ function lpdf.print(...)
+ return pdfprint(...)
+ end
-updaters.register("backend.update.pdf",function()
+ pdfbackend.codeinjections.print = lpdf.print
- pdfgetpos = pdf.getpos
- pdfgethpos = pdf.gethpos
- pdfgetvpos = pdf.getvpos
- pdfhasmatrix = pdf.hasmatrix
- pdfgetmatrix = pdf.getmatrix
- pdfprint = pdf.print
+ updaters.register("backend.update.lpdf",function()
+ pdfprint = pdf.print
+ end)
- pdfbackend.codeinjections.getpos = pdfgetpos
- pdfbackend.codeinjections.gethpos = pdfgethpos
- pdfbackend.codeinjections.getvpos = pdfgetvpos
+ -- todo
- lpdf.getpos = pdfgetpos
- lpdf.gethpos = pdfgethpos
- lpdf.getvpos = pdfgetvpos
- lpdf.print = pdfprint
+ updaters.register("backend.update.lpdf",function()
+ pdfhasmatrix = pdf.hasmatrix
+ pdfgetmatrix = pdf.getmatrix
+ end)
-end)
+ -- local function transform(llx,lly,urx,ury,rx,sx,sy,ry)
+ -- local x1 = llx * rx + lly * sy
+ -- local y1 = llx * sx + lly * ry
+ -- local x2 = llx * rx + ury * sy
+ -- local y2 = llx * sx + ury * ry
+ -- local x3 = urx * rx + lly * sy
+ -- local y3 = urx * sx + lly * ry
+ -- local x4 = urx * rx + ury * sy
+ -- local y4 = urx * sx + ury * ry
+ -- llx = min(x1,x2,x3,x4);
+ -- lly = min(y1,y2,y3,y4);
+ -- urx = max(x1,x2,x3,x4);
+ -- ury = max(y1,y2,y3,y4);
+ -- return llx, lly, urx, ury
+ -- end
+ --
+ -- function lpdf.transform(llx,lly,urx,ury) -- not yet used so unchecked
+ -- if pdfhasmatrix() then
+ -- local sx, rx, ry, sy = pdfgetmatrix()
+ -- local w, h = urx - llx, ury - lly
+ -- return llx, lly, llx + sy*w - ry*h, lly + sx*h - rx*w
+ -- -- return transform(llx,lly,urx,ury,sx,rx,ry,sy)
+ -- else
+ -- return llx, lly, urx, ury
+ -- end
+ -- end
--- local function transform(llx,lly,urx,ury,rx,sx,sy,ry)
--- local x1 = llx * rx + lly * sy
--- local y1 = llx * sx + lly * ry
--- local x2 = llx * rx + ury * sy
--- local y2 = llx * sx + ury * ry
--- local x3 = urx * rx + lly * sy
--- local y3 = urx * sx + lly * ry
--- local x4 = urx * rx + ury * sy
--- local y4 = urx * sx + ury * ry
--- llx = min(x1,x2,x3,x4);
--- lly = min(y1,y2,y3,y4);
--- urx = max(x1,x2,x3,x4);
--- ury = max(y1,y2,y3,y4);
--- return llx, lly, urx, ury
--- end
---
--- function lpdf.transform(llx,lly,urx,ury) -- not yet used so unchecked
--- if pdfhasmatrix() then
--- local sx, rx, ry, sy = pdfgetmatrix()
--- local w, h = urx - llx, ury - lly
--- return llx, lly, llx + sy*w - ry*h, lly + sx*h - rx*w
--- -- return transform(llx,lly,urx,ury,sx,rx,ry,sy)
--- else
--- return llx, lly, urx, ury
--- end
--- end
+ -- funny values for tx and ty
--- funny values for tx and ty
-
-function lpdf.rectangle(width,height,depth,offset)
- local tx, ty = pdfgetpos()
- if offset then
- tx = tx - offset
- ty = ty + offset
- width = width + 2*offset
- height = height + offset
- depth = depth + offset
- end
- if pdfhasmatrix() then
- local rx, sx, sy, ry = pdfgetmatrix()
- return
- factor * tx,
- factor * (ty - ry*depth + sx*width),
- factor * (tx + rx*width - sy*height),
- factor * (ty + ry*height - sx*width)
- else
- return
- factor * tx,
- factor * (ty - depth),
- factor * (tx + width),
- factor * (ty + height)
+ function lpdf.rectangle(width,height,depth,offset)
+ local tx, ty = pdfgetpos()
+ if offset then
+ tx = tx - offset
+ ty = ty + offset
+ width = width + 2*offset
+ height = height + offset
+ depth = depth + offset
+ end
+ if pdfhasmatrix() then
+ local rx, sx, sy, ry = pdfgetmatrix()
+ return
+ factor * tx,
+ factor * (ty - ry*depth + sx*width),
+ factor * (tx + rx*width - sy*height),
+ factor * (ty + ry*height - sx*width)
+ else
+ return
+ factor * tx,
+ factor * (ty - depth),
+ factor * (tx + width),
+ factor * (ty + height)
+ end
end
+
end
-- we could use a hash of predefined unicodes
@@ -462,10 +489,14 @@ do
tostring_d = function(t,contentonly,key)
if next(t) then
- local r, n = { }, 0
- for k in next, t do
- n = n + 1
- r[n] = k
+ local r, n, e = { }, 0
+ for k, v in next, t do
+ if k == "__extra__" then
+ e = v
+ else
+ n = n + 1
+ r[n] = k
+ end
end
sort(r)
for i=1,n do
@@ -495,6 +526,9 @@ do
r[i] = f_key_value(k,tostring(v))
end
end
+ if e then
+ r[n+1] = e
+ end
if contentonly then
return concat(r," ")
elseif key then
@@ -540,6 +574,10 @@ do
r[k] = tostring(v)
end
end
+ local e = t.__extra__
+ if e then
+ r[tn+1] = e
+ end
if contentonly then
return concat(r, " ")
elseif key then
@@ -605,11 +643,45 @@ local function value_r(t) return t[1] or 0 end -- null
local function value_v(t) return t[1] end
local function value_l(t) return t[1] end
+local function add_to_d(t,v)
+ local k = type(v)
+ if k == "string" then
+ if t.__extra__ then
+ t.__extra__ = t.__extra__ .. " " .. v
+ else
+ t.__extra__ = v
+ end
+ elseif k == "table" then
+ for k, v in next, v do
+ t[k] = v
+ end
+ end
+ return t
+end
+
+local function add_to_a(t,v)
+ local k = type(v)
+ if k == "string" then
+ if t.__extra__ then
+ t.__extra__ = t.__extra__ .. " " .. v
+ else
+ t.__extra__ = v
+ end
+ elseif k == "table" then
+ local n = #t
+ for i=1,#v do
+ n = n + 1
+ t[n] = v[i]
+ end
+ end
+ return t
+end
+
local function add_x(t,k,v) rawset(t,k,tostring(v)) end
local mt_x = { __lpdftype = "stream", __tostring = tostring_x, __call = value_x, __newindex = add_x }
-local mt_d = { __lpdftype = "dictionary", __tostring = tostring_d, __call = value_d }
-local mt_a = { __lpdftype = "array", __tostring = tostring_a, __call = value_a }
+local mt_d = { __lpdftype = "dictionary", __tostring = tostring_d, __call = value_d, __add = add_to_d }
+local mt_a = { __lpdftype = "array", __tostring = tostring_a, __call = value_a, __add = add_to_a }
local mt_u = { __lpdftype = "unicode", __tostring = tostring_u, __call = value_u }
local mt_s = { __lpdftype = "string", __tostring = tostring_s, __call = value_s }
local mt_p = { __lpdftype = "docstring", __tostring = tostring_p, __call = value_p }
@@ -666,60 +738,66 @@ local function pdfliteral(str,hex) -- can also produce a hex <> instead of () li
return setmetatable({ str, hex },mt_l)
end
-local cache = { } -- can be weak
+local pdfnumber, pdfconstant
-local function pdfnumber(n,default) -- 0-10
- if not n then
- n = default
- end
- local c = cache[n]
- if not c then
- c = setmetatable({ n },mt_n)
- -- cache[n] = c -- too many numbers
- end
- return c
-end
+do
-for i=-1,9 do cache[i] = pdfnumber(i) end
-
-local replacer = S("\0\t\n\r\f ()[]{}/%%#\\") / {
- ["\00"]="#00",
- ["\09"]="#09",
- ["\10"]="#0a",
- ["\12"]="#0c",
- ["\13"]="#0d",
- [ " " ]="#20",
- [ "#" ]="#23",
- [ "%" ]="#25",
- [ "(" ]="#28",
- [ ")" ]="#29",
- [ "/" ]="#2f",
- [ "[" ]="#5b",
- [ "\\"]="#5c",
- [ "]" ]="#5d",
- [ "{" ]="#7b",
- [ "}" ]="#7d",
-} + P(1)
-
-local escaped = Cs(Cc("/") * replacer^0)
-
-local cache = table.setmetatableindex(function(t,k)
- local v = setmetatable({ lpegmatch(escaped,k) }, mt_c)
- t[k] = v
- return v
-end)
+ local cache = { } -- can be weak
-local function pdfconstant(str,default)
- if not str then
- str = default or "none"
+ pdfnumber = function(n,default) -- 0-10
+ if not n then
+ n = default
+ end
+ local c = cache[n]
+ if not c then
+ c = setmetatable({ n },mt_n)
+ -- cache[n] = c -- too many numbers
+ end
+ return c
+ end
+
+ for i=-1,9 do cache[i] = pdfnumber(i) end
+
+ local replacer = S("\0\t\n\r\f ()[]{}/%%#\\") / {
+ ["\00"]="#00",
+ ["\09"]="#09",
+ ["\10"]="#0a",
+ ["\12"]="#0c",
+ ["\13"]="#0d",
+ [ " " ]="#20",
+ [ "#" ]="#23",
+ [ "%" ]="#25",
+ [ "(" ]="#28",
+ [ ")" ]="#29",
+ [ "/" ]="#2f",
+ [ "[" ]="#5b",
+ [ "\\"]="#5c",
+ [ "]" ]="#5d",
+ [ "{" ]="#7b",
+ [ "}" ]="#7d",
+ } + P(1)
+
+ local escaped = Cs(Cc("/") * replacer^0)
+
+ local cache = table.setmetatableindex(function(t,k)
+ local v = setmetatable({ lpegmatch(escaped,k) }, mt_c)
+ t[k] = v
+ return v
+ end)
+
+ pdfconstant = function(str,default)
+ if not str then
+ str = default or "none"
+ end
+ return cache[str]
end
- return cache[str]
-end
-local escaped = Cs(replacer^0)
+ local escaped = Cs(replacer^0)
+
+ function lpdf.escaped(str)
+ return lpegmatch(escaped,str) or str
+ end
-function lpdf.escaped(str)
- return lpegmatch(escaped,str) or str
end
local pdfnull, pdfboolean, pdfreference, pdfverbose
@@ -800,13 +878,7 @@ function lpdf.reserveobject(name)
return r
end
--- lpdf.reserveobject = pdfreserveobject
--- lpdf.immediateobject = pdfimmediateobject
--- lpdf.deferredobject = pdfdeferredobject
--- lpdf.referenceobject = pdfreferenceobject
-
-local pagereference = pdf.getpageref or pdf.pageref -- tex.pdfpageref is obsolete
-local nofpages = 0
+local nofpages = 0
function lpdf.pagereference(n)
if nofpages == 0 then
@@ -816,9 +888,9 @@ function lpdf.pagereference(n)
end
end
if n > nofpages then
- return pagereference(nofpages) -- or 1, could be configureable
+ return pdfgetpagereference(nofpages) -- or 1, could be configureable
else
- return pagereference(n)
+ return pdfgetpagereference(n)
end
end
@@ -826,6 +898,14 @@ function lpdf.nofpages()
return structures.pages.nofpages
end
+function lpdf.obj(...)
+ pdfdeferredobject(...)
+end
+
+function lpdf.immediateobj(...)
+ pdfimmediateobject(...)
+end
+
function lpdf.delayedobject(data,n)
if n then
pdfdeferredobject(n,data)
@@ -1030,7 +1110,7 @@ function lpdf.finalizedocument()
if not environment.initex then
run(documentfinalizers,"document")
function lpdf.finalizedocument()
- report_finalizing("serious error: the document is finalized multiple times")
+ -- report_finalizing("serious error: the document is finalized multiple times")
function lpdf.finalizedocument() end
end
end
@@ -1061,18 +1141,16 @@ do
local info = pdfdictionary { Type = pdfconstant("Info") } -- nicer, but when we assign we nil the Type
----- names = pdfdictionary { Type = pdfconstant("Names") } -- nicer, but when we assign we nil the Type
- local function flushcatalog()
+ local function checkcatalog()
if not environment.initex then
trace_flush("catalog")
- catalog.Type = nil
- pdfsetcatalog(catalog())
+ return true
end
end
- local function flushinfo()
+ local function checkinfo()
if not environment.initex then
trace_flush("info")
- info.Type = nil
if lpdf.majorversion() > 1 then
for k, v in next, info do
if k == "CreationDate" or k == "ModDate" then
@@ -1082,17 +1160,35 @@ do
end
end
end
+ return true
+ end
+ end
+
+ local function flushcatalog()
+ if checkcatalog() then
+ catalog.Type = nil
+ pdfsetcatalog(catalog())
+ end
+ end
+
+ local function flushinfo()
+ if checkinfo() then
+ info.Type = nil
pdfsetinfo(info())
end
end
- -- local function flushnames()
- -- if not environment.initex then
- -- trace_flush("names")
- -- names.Type = nil
- -- pdfsetnames(names())
- -- end
- -- end
+ function lpdf.getcatalog()
+ if checkcatalog() then
+ return pdfreference(pdfimmediateobject(tostring(catalog)))
+ end
+ end
+
+ function lpdf.getinfo()
+ if checkinfo() then
+ return pdfreference(pdfimmediateobject(tostring(info)))
+ end
+ end
function lpdf.addtocatalog(k,v)
if not (lpdf.protectresources and catalog[k]) then
@@ -1134,20 +1230,19 @@ do
end
end
- 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 r_extgstates, r_colorspaces, r_patterns, r_shades
+ local d_extgstates, d_colorspaces, d_patterns, d_shades
+ local p_extgstates, p_colorspaces, p_patterns, p_shades
- 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 checkextgstates () if d_extgstates then addtopageresources("ExtGState", p_extgstates ) end end
+ local function checkcolorspaces() if d_colorspaces then addtopageresources("ColorSpace",p_colorspaces) end end
+ local function checkpatterns () if d_patterns then addtopageresources("Pattern", p_patterns ) end end
+ local function checkshades () if d_shades then addtopageresources("Shading", p_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 function flushextgstates () if d_extgstates then trace_flush("extgstates") pdfimmediateobject(r_extgstates, tostring(d_extgstates )) end end
+ local function flushcolorspaces() if d_colorspaces then trace_flush("colorspaces") pdfimmediateobject(r_colorspaces,tostring(d_colorspaces)) end end
+ local function flushpatterns () if d_patterns then trace_flush("patterns") pdfimmediateobject(r_patterns, tostring(d_patterns )) end end
+ local function flushshades () if d_shades then trace_flush("shades") pdfimmediateobject(r_shades, tostring(d_shades )) end end
-- patterns are special as they need resources to so we can get recursive references and in that case
-- acrobat doesn't show anything (other viewers handle it well)
@@ -1156,10 +1251,10 @@ do
-- todo: force when not yet set
function lpdf.collectedresources(options)
- 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
+ local ExtGState = d_extgstates and next(d_extgstates ) and p_extgstates
+ local ColorSpace = d_colorspaces and next(d_colorspaces) and p_colorspaces
+ local Pattern = d_patterns and next(d_patterns ) and p_patterns
+ local Shading = d_shades and next(d_shades ) and p_shades
if options and options.patterns == false then
Pattern = nil
end
@@ -1176,14 +1271,49 @@ do
return collected()
end
else
- return ""
+ if options and options.serialize == false then
+ return pdfdictionary { }
+ else
+ return ""
+ end
+ end
+ end
+
+ function lpdf.adddocumentextgstate (k,v)
+ if not d_extgstates then
+ r_extgstates = pdfreserveobject()
+ d_extgstates = pdfdictionary()
+ p_extgstates = pdfreference(r_extgstates)
end
+ d_extgstates[k] = v
end
- function lpdf.adddocumentextgstate (k,v) d_extgstates [k] = v end
- 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
+ function lpdf.adddocumentcolorspace(k,v)
+ if not d_colorspaces then
+ r_colorspaces = pdfreserveobject()
+ d_colorspaces = pdfdictionary()
+ p_colorspaces = pdfreference(r_colorspaces)
+ end
+ d_colorspaces[k] = v
+ end
+
+ function lpdf.adddocumentpattern(k,v)
+ if not d_patterns then
+ r_patterns = pdfreserveobject()
+ d_patterns = pdfdictionary()
+ p_patterns = pdfreference(r_patterns)
+ end
+ d_patterns[k] = v
+ end
+
+ function lpdf.adddocumentshade(k,v)
+ if not d_shades then
+ r_shades = pdfreserveobject()
+ d_shades = pdfdictionary()
+ p_shades = pdfreference(r_shades)
+ end
+ d_shades[k] = v
+ end
registerdocumentfinalizer(flushextgstates,3,"extended graphic states")
registerdocumentfinalizer(flushcolorspaces,3,"color spaces")
@@ -1320,7 +1450,6 @@ function lpdf.checkedvalue(value,variant) -- code not shared
end
end
end
- -- return nil
end
function lpdf.limited(n,min,max,default)
@@ -1340,60 +1469,6 @@ function lpdf.limited(n,min,max,default)
end
end
--- if not pdfreferenceobject then
---
--- 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
-
--- setmetatable(pdf, {
--- __index = function(t,k)
--- if k == "info" then return pdf.getinfo()
--- elseif k == "catalog" then return pdf.getcatalog()
--- elseif k == "names" then return pdf.getnames()
--- elseif k == "trailer" then return pdf.gettrailer()
--- elseif k == "pageattribute" then return pdf.getpageattribute()
--- elseif k == "pageattributes" then return pdf.getpageattributes()
--- elseif k == "pageresources" then return pdf.getpageresources()
--- elseif
--- return nil
--- end
--- end,
--- __newindex = function(t,k,v)
--- if k == "info" then return pdf.setinfo(v)
--- elseif k == "catalog" then return pdf.setcatalog(v)
--- elseif k == "names" then return pdf.setnames(v)
--- elseif k == "trailer" then return pdf.settrailer(v)
--- elseif k == "pageattribute" then return pdf.setpageattribute(v)
--- elseif k == "pageattributes" then return pdf.setpageattributes(v)
--- elseif k == "pageresources" then return pdf.setpageresources(v)
--- else
--- rawset(t,k,v)
--- end
--- end,
--- })
-
-- The next variant of ActualText is what Taco and I could come up with
-- eventually. As of September 2013 Acrobat copies okay, Sumatra copies a
-- question mark, pdftotext injects an extra space and Okular adds a
@@ -1547,5 +1622,57 @@ function lpdf.copystring(v)
end
end
-lpdf.includechar = pdf.includechar
-lpdf.includefont = pdf.includefont
+do
+
+ local pdf_includechar = pdf.includechar
+ local pdf_includefont = pdf.includefont
+ local pdf_setmapfile = pdf.mapfile
+ local pdf_setmapline = pdf.mapline
+
+ updaters.register("backend.update.lpdf",function()
+ pdf_includechar = pdf.includechar
+ pdf_includefont = pdf.includefont
+ pdf_setmapfile = pdf.mapfile
+ pdf_setmapline = pdf.mapline
+ end)
+
+ function lpdf.includechar(...) pdf_includechar(...) end
+ function lpdf.includefont(...) pdf_includefont(...) end
+
+ function lpdf.setmapfile(...) pdf_setmapfile(...) end
+ function lpdf.setmapline(...) pdf_setmapline(...) end
+
+end
+
+do
+
+ -- This is obsolete but old viewers might still use it as directive
+ -- for what to send to a postscript printer.
+
+ local a_procset, d_procset
+
+ function lpdf.procset(dict)
+ if not a_procset then
+ a_procset = pdfreference(pdfimmediateobject(pdfarray {
+ pdfconstant("PDF"),
+ pdfconstant("Text"),
+ pdfconstant("ImageB"),
+ pdfconstant("ImageC"),
+ pdfconstant("ImageI"),
+ }))
+ end
+ if dict then
+ if not d_procset then
+ d_procset = pdfreference(pdfimmediateobject(pdfdictionary {
+ ProcSet = a_procset
+ }))
+ end
+ return d_procset
+ else
+ return a_procset
+ end
+ end
+
+end
+
+