summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/context/base/mkiv/lpdf-ini.lua
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/tex/context/base/mkiv/lpdf-ini.lua')
-rw-r--r--Master/texmf-dist/tex/context/base/mkiv/lpdf-ini.lua128
1 files changed, 63 insertions, 65 deletions
diff --git a/Master/texmf-dist/tex/context/base/mkiv/lpdf-ini.lua b/Master/texmf-dist/tex/context/base/mkiv/lpdf-ini.lua
index ec837449f7e..2163e874852 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/lpdf-ini.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/lpdf-ini.lua
@@ -12,12 +12,13 @@ local setmetatable, getmetatable, type, next, tostring, tonumber, rawset = setme
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 utfchar, utfbyte, utfvalues = utf.char, utf.byte, utf.values
local sind, cosd, max, min = math.sind, math.cosd, math.max, math.min
-local sort = table.sort
+local sort, sortedhash = table.sort, table.sortedhash
local P, C, R, S, Cc, Cs, V = lpeg.P, lpeg.C, lpeg.R, lpeg.S, lpeg.Cc, lpeg.Cs, lpeg.V
local lpegmatch, lpegpatterns = lpeg.match, lpeg.patterns
local formatters = string.formatters
local isboolean = string.is_boolean
local rshift = bit32.rshift
+local osdate, ostime = os.date, os.time
local report_objects = logs.reporter("backend","objects")
local report_finalizing = logs.reporter("backend","finalizing")
@@ -57,7 +58,7 @@ lpdf.flags = lpdf.flags or { } -- will be filled later
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 trace_details = false trackers.register("backend.details", function(v) trace_details = v end)
do
@@ -169,23 +170,25 @@ end
local pdfgetpagereference
updaters.register("backend.update.lpdf",function()
- pdfreserveobject = pdf.reserveobj
- pdfimmediateobject = pdf.immediateobj
- pdfdeferredobject = pdf.obj
- pdfreferenceobject = pdf.refobj
+ pdfreserveobject = pdf.reserveobj
+ pdfimmediateobject = pdf.immediateobj
+ pdfdeferredobject = pdf.obj
+ pdfreferenceobject = pdf.refobj
- pdfgetpagereference = pdf.getpageref
+ pdfgetpagereference = pdf.getpageref
- pdfsetpageresources = pdf.setpageresources
- pdfsetpageattributes = pdf.setpageattributes
- pdfsetpagesattributes = pdf.setpagesattributes
+ pdfsetpageresources = pdf.setpageresources
+ pdfsetpageattributes = pdf.setpageattributes
+ pdfsetpagesattributes = pdf.setpagesattributes
end)
local jobpositions = job.positions
local getpos = jobpositions.getpos
+local getrpos = jobpositions.getrpos
jobpositions.registerhandlers {
getpos = pdf.getpos,
+ -- getrpos = pdf.getrpos,
gethpos = pdf.gethpos,
getvpos = pdf.getvpos,
}
@@ -204,8 +207,6 @@ do
return pdfprint(...)
end
- pdfbackend.codeinjections.print = lpdf.print -- will go
-
-- local function transform(llx,lly,urx,ury,rx,sx,sy,ry)
-- local x1 = llx * rx + lly * sy
-- local y1 = llx * sx + lly * ry
@@ -236,7 +237,7 @@ do
-- funny values for tx and ty
function lpdf.rectangle(width,height,depth,offset)
- local tx, ty = getpos()
+ local tx, ty = getpos() -- pdfgetpos, maybe some day use dir here
if offset then
tx = tx - offset
ty = ty + offset
@@ -866,18 +867,21 @@ end
local nofpages = 0
-function lpdf.pagereference(n)
+local texgetcount = tex.getcount
+
+function lpdf.pagereference(n,complete) -- true | false | nil | n [true,false]
if nofpages == 0 then
nofpages = structures.pages.nofpages
if nofpages == 0 then
nofpages = 1
end
end
- if n > nofpages then
- return pdfgetpagereference(nofpages) -- or 1, could be configureable
- else
- return pdfgetpagereference(n)
+ if n == true or not n then
+ complete = n
+ n = texgetcount("realpageno")
end
+ local r = n > nofpages and pdfgetpagereference(nofpages) or pdfgetpagereference(n)
+ return complete and pdfreference(r) or r
end
function lpdf.nofpages()
@@ -907,7 +911,7 @@ function lpdf.flushobject(name,data)
local named = names[name]
if named then
if not trace_objects then
- elseif trace_detail then
+ elseif trace_details then
report_objects("flushing data to reserved object with name %a, data: %S",name,data)
else
report_objects("flushing data to reserved object with name %a",name)
@@ -915,7 +919,7 @@ function lpdf.flushobject(name,data)
return pdfimmediateobject(named,tostring(data))
else
if not trace_objects then
- elseif trace_detail then
+ elseif trace_details then
report_objects("flushing data to reserved object with number %s, data: %S",name,data)
else
report_objects("flushing data to reserved object with number %s",name)
@@ -923,7 +927,7 @@ function lpdf.flushobject(name,data)
return pdfimmediateobject(name,tostring(data))
end
else
- if trace_objects and trace_detail then
+ if trace_objects and trace_details then
report_objects("flushing data: %S",name)
end
return pdfimmediateobject(tostring(name))
@@ -1249,32 +1253,47 @@ do
-- todo: share them
-- todo: force when not yet set
+ local f_font = formatters["%s%d"]
+
function lpdf.collectedresources(options)
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
+ local Font
if options and options.patterns == false then
Pattern = nil
end
- if ExtGState or ColorSpace or Pattern or Shading then
+ local fonts = options and options.fonts
+ if fonts and next(fonts) then
+ local pdfgetfontobjnumber = lpdf.getfontobjnumber
+ if pdfgetfontobjnumber then
+ local prefix = options.fontprefix or "F"
+ Font = pdfdictionary { }
+ for k, v in sortedhash(fonts) do
+ Font[f_font(prefix,v)] = pdfreference(pdfgetfontobjnumber(k))
+ end
+ end
+ end
+ if ExtGState or ColorSpace or Pattern or Shading or Font then
local collected = pdfdictionary {
ExtGState = ExtGState,
ColorSpace = ColorSpace,
Pattern = Pattern,
Shading = Shading,
+ Font = Font,
}
if options and options.serialize == false then
return collected
else
return collected()
end
+ elseif options and options.notempty then
+ return nil
+ elseif options and options.serialize == false then
+ return pdfdictionary { }
else
- if options and options.serialize == false then
- return pdfdictionary { }
- else
- return ""
- end
+ return ""
end
end
@@ -1383,8 +1402,13 @@ do
lpdf.settime(tonumber(resolvers.variable("start_time")) or tonumber(resolvers.variable("SOURCE_DATE_EPOCH"))) -- bah
function lpdf.pdftimestamp(str)
- local Y, M, D, h, m, s, Zs, Zh, Zm = match(str,"^(%d%d%d%d)%-(%d%d)%-(%d%d)T(%d%d):(%d%d):(%d%d)([%+%-])(%d%d):(%d%d)$")
- return Y and format("D:%s%s%s%s%s%s%s%s'%s'",Y,M,D,h,m,s,Zs,Zh,Zm)
+ local t = type(str)
+ if t == "string" then
+ local Y, M, D, h, m, s, Zs, Zh, Zm = match(str,"^(%d%d%d%d)%-(%d%d)%-(%d%d)T(%d%d):(%d%d):(%d%d)([%+%-])(%d%d):(%d%d)$")
+ return Y and format("D:%s%s%s%s%s%s%s%s'%s'",Y,M,D,h,m,s,Zs,Zh,Zm)
+ else
+ return osdate("D:%Y%m%d%H%M%S",t == "number" and str or ostime()) -- maybe "!D..." : universal time
+ end
end
function lpdf.id(date)
@@ -1478,41 +1502,23 @@ end
do
- local f_actual_text_one = formatters["BT /Span << /ActualText <feff%04x> >> BDC %s EMC ET"]
- local f_actual_text_two = formatters["BT /Span << /ActualText <feff%04x%04x> >> BDC %s EMC ET"]
- local f_actual_text_one_b = formatters["BT /Span << /ActualText <feff%04x> >> BDC"]
- local f_actual_text_two_b = formatters["BT /Span << /ActualText <feff%04x%04x> >> BDC"]
- local f_actual_text_b = formatters["BT /Span << /ActualText <feff%s> >> BDC"]
- local s_actual_text_e = "EMC ET"
- local f_actual_text_b_not = formatters["/Span << /ActualText <feff%s> >> BDC"]
- local f_actual_text_one_b_not = formatters["/Span << /ActualText <feff%04x> >> BDC"]
- local f_actual_text_two_b_not = formatters["/Span << /ActualText <feff%04x%04x> >> BDC"]
- local s_actual_text_e_not = "EMC"
- local f_actual_text = formatters["/Span <</ActualText %s >> BDC"]
+ local f_actual_text_p = formatters["BT /Span << /ActualText <feff%s> >> BDC %s EMC ET"]
+ local f_actual_text_b = formatters["BT /Span << /ActualText <feff%s> >> BDC"]
+ local s_actual_text_e = "EMC ET"
+ local f_actual_text_b_not = formatters["/Span << /ActualText <feff%s> >> BDC"]
+ local s_actual_text_e_not = "EMC"
+ local f_actual_text = formatters["/Span <</ActualText %s >> BDC"]
local context = context
local pdfdirect = nodes.pool.directliteral -- we can use nuts.write deep down
-
- -- todo: use tounicode from the font mapper
-
- -- floor(unicode/1024) => rshift(unicode,10) -- better for 5.3
+ local tounicode = fonts.mappings.tounicode
function codeinjections.unicodetoactualtext(unicode,pdfcode)
- if unicode < 0x10000 then
- return f_actual_text_one(unicode,pdfcode)
- else
- return f_actual_text_two(rshift(unicode,10)+0xD800,unicode%1024+0xDC00,pdfcode)
- end
+ return f_actual_text_p(type(unicode) == "string" and unicode or tounicode(unicode),pdfcode)
end
function codeinjections.startunicodetoactualtext(unicode)
- if type(unicode) == "string" then
- return f_actual_text_b(unicode)
- elseif unicode < 0x10000 then
- return f_actual_text_one_b(unicode)
- else
- return f_actual_text_two_b(rshift(unicode,10)+0xD800,unicode%1024+0xDC00)
- end
+ return f_actual_text_b(type(unicode) == "string" and unicode or tounicode(unicode))
end
function codeinjections.stopunicodetoactualtext()
@@ -1520,13 +1526,7 @@ do
end
function codeinjections.startunicodetoactualtextdirect(unicode)
- if type(unicode) == "string" then
- return f_actual_text_b_not(unicode)
- elseif unicode < 0x10000 then
- return f_actual_text_one_b_not(unicode)
- else
- return f_actual_text_two_b_not(rshift(unicode,10)+0xD800,unicode%1024+0xDC00)
- end
+ return f_actual_text_b_not(type(unicode) == "string" and unicode or tounicode(unicode))
end
function codeinjections.stopunicodetoactualtextdirect()
@@ -1689,5 +1689,3 @@ end
if environment.arguments.nocompression then
lpdf.setcompression(0,0,true)
end
-
-