summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/context/base/back-pdf.lua
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/tex/context/base/back-pdf.lua')
-rw-r--r--Master/texmf-dist/tex/context/base/back-pdf.lua267
1 files changed, 206 insertions, 61 deletions
diff --git a/Master/texmf-dist/tex/context/base/back-pdf.lua b/Master/texmf-dist/tex/context/base/back-pdf.lua
index 54e22f1a2bd..33cb8c97558 100644
--- a/Master/texmf-dist/tex/context/base/back-pdf.lua
+++ b/Master/texmf-dist/tex/context/base/back-pdf.lua
@@ -6,7 +6,9 @@ if not modules then modules = { } end modules ['back-pdf'] = {
license = "see context related readme files"
}
--- we will move code to lpdf-* files (second cleanup stage)
+-- we will move code to lpdf-* files (second cleanup stage in 2011/2012)
+
+-- the push/pop is a mess (only needed for calculate ...) .. will be done differently
--[[ldx--
<p>This module implements a couple of cleanup methods. We need these
@@ -20,29 +22,30 @@ local char, byte, format, gsub, rep, gmatch = string.char, string.byte, string.f
local concat = table.concat
local round = math.round
local utfcharacters, utfvalues = string.utfcharacters, string.utfvalues
-local texsprint, texwrite = tex.sprint, tex.write
-local ctxcatcodes = tex.ctxcatcodes
-local copy_node = node.copy
+local backends, lpdf, nodes, node = backends, lpdf, nodes, node
+
+local copy_node = node.copy
+
+local nodeinjections = backends.pdf.nodeinjections
+local codeinjections = backends.pdf.codeinjections
+local registrations = backends.pdf.registrations
-local nodeinjections = backends.pdf.nodeinjections
-local codeinjections = backends.pdf.codeinjections
-local registrations = backends.pdf.registrations
+local nodepool = nodes.pool
-local pdfliteral, register = nodes.pdfliteral, nodes.register
+local register = nodepool.register
-local pdfconstant = lpdf.constant
-local pdfstring = lpdf.string
-local pdfdictionary = lpdf.dictionary
-local pdfarray = lpdf.array
-local pdfreference = lpdf.reference
-local pdfverbose = lpdf.verbose
-local pdfflushobject = lpdf.flushobject
-local pdfreserveobject = lpdf.reserveobject
-local pdfannotation = nodes.pdfannotation
+local pdfconstant = lpdf.constant
+local pdfstring = lpdf.string
+local pdfdictionary = lpdf.dictionary
+local pdfarray = lpdf.array
+local pdfreference = lpdf.reference
+local pdfverbose = lpdf.verbose
+local pdfflushobject = lpdf.flushobject
+local pdfimmediateobject = lpdf.immediateobject
-local pdfreserveobj = pdf.reserveobj
-local pdfimmediateobj = pdf.immediateobj
+local pdfliteral = nodepool.pdfliteral
+local pdfannotation_node = nodepool.pdfannotation
function nodeinjections.rgbcolor(r,g,b)
return register(pdfliteral(format("%s %s %s rg %s %s %s RG",r,g,b,r,g,b)))
@@ -86,9 +89,19 @@ end
local cache = { }
+function codeinjections.startlayer(name)
+ codeinjections.useviewerlayer(name)
+ return format("/OC /%s BDC",name)
+end
+
+function codeinjections.stoplayer(name)
+ return "EMC"
+end
+
function nodeinjections.startlayer(name)
local c = cache[name]
if not c then
+ codeinjections.useviewerlayer(name)
c = register(pdfliteral(format("/OC /%s BDC",name)))
cache[name] = c
end
@@ -103,17 +116,18 @@ end
local cache = { }
-function nodeinjections.switchlayer(name)
+function nodeinjections.switchlayer(name) -- not used, optimization
local c = cache[name]
if not c then
+ codeinjections.useviewerlayer(name)
c = register(pdfliteral(format("EMC /OC /%s BDC",name)))
end
return copy_node(c)
end
--- code
+-- code, will move to lpdf-*
-function codeinjections.insertmovie(specification)
+function nodeinjections.insertmovie(specification)
-- managed in figure inclusion: width, height, factor, repeat, controls, preview, label, foundname
local width = specification.width
local height = specification.height
@@ -134,12 +148,12 @@ function codeinjections.insertmovie(specification)
Movie = moviedict,
A = controldict,
}
- node.write(pdfannotation(width,height,0,action()))
+ node.write(pdfannotation_node(width,height,0,action()))
end
-function codeinjections.insertsound(specification)
+function nodeinjections.insertsound(specification)
-- rmanaged in interaction: repeat, label, foundname
- local soundclip = interactions.soundclip(specification.label)
+ local soundclip = interactions.soundclips.soundclip(specification.label)
if soundclip then
local controldict = pdfdictionary {
Mode = (specification["repeat"] and pdfconstant("Repeat")) or nil
@@ -154,7 +168,7 @@ function codeinjections.insertsound(specification)
Movie = sounddict,
A = controldict,
}
- node.write(pdfannotation(0,0,0,action()))
+ node.write(pdfannotation_node(0,0,0,action()))
end
end
@@ -179,14 +193,22 @@ local gray_function = "%s mul"
local documentcolorspaces = pdfdictionary()
local spotcolorhash = { } -- not needed
-local spotcolornames = { }
-local indexcolorhash = { }
-local delayedindexcolors = { }
+local spotcolornames = { }
+local indexcolorhash = { }
+local delayedindexcolors = { }
function registrations.spotcolorname(name,e)
spotcolornames[name] = e or name
end
+function registrations.getspotcolorreference(name)
+ return spotcolorhash[name]
+end
+
+-- beware: xpdf/okular/evince cannot handle the spot->process shade
+
+local processcolors
+
local function registersomespotcolor(name,noffractions,names,p,colorspace,range,funct)
noffractions = tonumber(noffractions) or 1 -- to be checked
if noffractions == 0 then
@@ -197,14 +219,20 @@ local function registersomespotcolor(name,noffractions,names,p,colorspace,range,
Domain = { 0, 1 },
Range = range,
}
- local n = pdfimmediateobj("stream",format("{ %s }",funct),dictionary())
+ local calculations = pdfimmediateobject("stream",format("{ %s }",funct),dictionary()) -- todo: lpdf.stream
+ -- local calculations = pdfobject {
+ -- type = "stream",
+ -- immediate = true,
+ -- string = format("{ %s }",funct),
+ -- attr = dictionary(),
+ -- }
local array = pdfarray {
pdf_separation,
pdfconstant(spotcolornames[name] or name),
colorspace,
- pdfreference(n),
+ pdfreference(calculations),
}
- local m = pdfimmediateobj(tostring(array))
+ local m = pdfimmediateobject(tostring(array))
local mr = pdfreference(m)
spotcolorhash[name] = m
documentcolorspaces[name] = mr
@@ -212,24 +240,55 @@ local function registersomespotcolor(name,noffractions,names,p,colorspace,range,
else
local cnames = pdfarray()
local domain = pdfarray()
+ local colorants = pdfdictionary()
for n in gmatch(names,"[^,]+") do
- cnames[#cnames+1] = pdfconstant(spotcolornames[n] or n)
+ local name = spotcolornames[n] or n
+ if n == "cyan" then
+ name = "Cyan"
+ elseif n == "magenta" then
+ name = "Magenta"
+ elseif n == "yellow" then
+ name = "Yellow"
+ elseif n == "black" then
+ name = "Black"
+ else
+ colorants[name] = pdfreference(spotcolorhash[name] or spotcolorhash[n])
+ end
+ cnames[#cnames+1] = pdfconstant(name)
domain[#domain+1] = 0
domain[#domain+1] = 1
end
+ if not processcolors then
+ local specification = pdfdictionary {
+ ColorSpace = pdfconstant("DeviceCMYK"),
+ Components = pdfarray {
+ pdfconstant("Cyan"),
+ pdfconstant("Magenta"),
+ pdfconstant("Yellow"),
+ pdfconstant("Black")
+ }
+ }
+ processcolors = pdfreference(pdfimmediateobject(tostring(specification)))
+ end
local dictionary = pdfdictionary {
FunctionType = 4,
Domain = domain,
Range = range,
}
- local n = pdfimmediateobj("stream",format("{ %s %s }",rep("pop ",noffractions),funct),dictionary())
+ local calculation = pdfimmediateobject("stream",format("{ %s %s }",rep("pop ",noffractions),funct),dictionary())
+ local channels = pdfdictionary {
+ Subtype = pdfconstant("NChannel"),
+ Colorants = colorants,
+ Process = processcolors,
+ }
local array = pdfarray {
pdf_device_n,
cnames,
colorspace,
- pdfreference(n),
+ pdfreference(calculation),
+ lpdf.shareobjectreference(tostring(channels)), -- optional but needed for shades
}
- local m = pdfimmediateobj(tostring(array))
+ local m = pdfimmediateobject(tostring(array))
local mr = pdfreference(m)
spotcolorhash[name] = m
documentcolorspaces[name] = mr
@@ -237,7 +296,9 @@ local function registersomespotcolor(name,noffractions,names,p,colorspace,range,
end
end
-function registersomeindexcolor(name,noffractions,names,p,colorspace,range,funct)
+-- wrong name
+
+local function registersomeindexcolor(name,noffractions,names,p,colorspace,range,funct)
noffractions = tonumber(noffractions) or 1 -- to be checked
local cnames = pdfarray()
local domain = pdfarray()
@@ -256,7 +317,7 @@ function registersomeindexcolor(name,noffractions,names,p,colorspace,range,funct
Domain = domain,
Range = range,
}
- local n = pdfimmediateobj("stream",format("{ %s %s }",rep("exch pop ",noffractions),funct),dictionary()) -- exch pop
+ local n = pdfimmediateobject("stream",format("{ %s %s }",rep("exch pop ",noffractions),funct),dictionary()) -- exch pop
local a = pdfarray {
pdf_device_n,
cnames,
@@ -280,7 +341,7 @@ function registersomeindexcolor(name,noffractions,names,p,colorspace,range,funct
vector[#vector+1] = concat(set)
end
vector = pdfverbose { "<", concat(vector, " "), ">" }
- local n = pdfimmediateobj(tostring(pdfarray{ pdf_indexed, a, 255, vector }))
+ local n = pdfimmediateobject(tostring(pdfarray{ pdf_indexed, a, 255, vector }))
lpdf.adddocumentcolorspace(format("%s_indexed",name),pdfreference(n))
return n
end
@@ -289,13 +350,11 @@ end
local function delayindexcolor(name,names,func)
local hash = (names ~= "" and names) or name
- -- logs.report("index colors","delaying '%s'",name)
delayedindexcolors[hash] = func
end
local function indexcolorref(name) -- actually, names (parent) is the hash
if not indexcolorhash[name] then
- -- logs.report("index colors","registering '%s'",name)
local delayedindexcolor = delayedindexcolors[name]
if type(delayedindexcolor) == "function" then
indexcolorhash[name] = delayedindexcolor()
@@ -395,7 +454,7 @@ function registrations.transparency(n,a,t)
BM = transparencies[1],
AIS = false,
}
- local m = pdfimmediateobj(tostring(d))
+ local m = pdfimmediateobject(tostring(d))
local mr = pdfreference(m)
transparencyhash[0] = m
documenttransparencies[0] = mr
@@ -407,10 +466,10 @@ function registrations.transparency(n,a,t)
Type = pdf_extgstate,
ca = tonumber(t),
CA = tonumber(t),
- BM = transparencies[a] or transparencies[0],
+ BM = transparencies[tonumber(a)] or transparencies[0],
AIS = false,
}
- local m = pdfimmediateobj(tostring(d))
+ local m = pdfimmediateobject(tostring(d))
local mr = pdfreference(m)
transparencyhash[n] = m
documenttransparencies[n] = mr
@@ -418,6 +477,8 @@ function registrations.transparency(n,a,t)
end
end
+-- overloaded in lpdf-xmp:
+
function codeinjections.adddocumentinfo(key,value)
lpdf.addtoinfo(key,lpdf.tosixteen(value))
end
@@ -425,11 +486,11 @@ end
-- graphics
function codeinjections.setfigurealternative(data,figure)
- local display = data.request.display
+ local request = data.request
+ local display = request.display
if display and display ~= "" then
- local request = data.request
- figures.push {
- name = request.display,
+ local nested = figures.push {
+ name = display,
page = request.page,
size = request.size,
prefix = request.prefix,
@@ -442,28 +503,112 @@ function codeinjections.setfigurealternative(data,figure)
if displayfigure then
-- figure.aform = true
img.immediatewrite(figure)
- local a = lpdf.array {
- lpdf.dictionary {
- Image = lpdf.reference(figure.objnum),
+ local a = pdfarray {
+ pdfdictionary {
+ Image = pdfreference(figure.objnum),
DefaultForPrinting = true,
}
}
- local d = lpdf.dictionary {
- Alternates = lpdf.reference(pdf.immediateobj(tostring(a))),
+ local d = pdfdictionary {
+ Alternates = pdfreference(pdfimmediateobject(tostring(a))),
}
displayfigure.attr = d()
- return displayfigure, figures.current()
+ figures.pop()
+ return displayfigure, nested
+ else
+ figures.pop()
end
end
end
--- eventually we need to load this runtime
---
--- backends.install((environment and environment.arguments and environment.arguments.backend) or "pdf")
---
--- but now we need to force this as we also load the pdf tex part which hooks into all kind of places
+function codeinjections.getpreviewfigure(request)
+ local figure = figures.initialize(request)
+ if not figure then
+ return
+ end
+ figure = figures.identify(figure)
+ if not figure then
+ return
+ end
+ figure = figures.check(figure)
+ if not figure then
+ return
+ end
+ local image = figure.status.private
+ if image then
+ img.immediatewrite(image)
+ end
+ return figure
+end
+
+function codeinjections.setfiguremask(data,figure) -- mark
+ local request = data.request
+ local mask = request.mask
+ if mask and mask ~= "" then
+ figures.push {
+ name = mask,
+ page = request.page,
+ size = request.size,
+ prefix = request.prefix,
+ cache = request.cache,
+ width = request.width,
+ height = request.height,
+ }
+ figures.identify()
+ local maskfigure = figures.check()
+ if maskfigure then
+ local image = maskfigure.status.private
+ if image then
+ img.immediatewrite(image)
+ local d = pdfdictionary {
+ Interpolate = false,
+ SMask = pdfreference(image.objnum),
+ }
+ figure.attr = d()
+ end
+ end
+ figures.pop()
+ end
+end
+
+local outputfilename
+
+function codeinjections.getoutputfilename()
+ if not outputfilename then
+ outputfilename = file.addsuffix(tex.jobname,"pdf")
+ end
+ return outputfilename
+end
+
+-- temp hack
+
+local factor = number.dimenfactors.bp
+
+function img.package(image)
+ local boundingbox = image.bbox
+ local imagetag = "Im" .. image.index
+ local resources = pdfdictionary {
+ ProcSet = pdfarray {
+ pdfconstant("PDF"),
+ pdfconstant("ImageC")
+ },
+ Resources = pdfdictionary {
+ XObject = pdfdictionary {
+ [imagetag] = pdfreference(image.objnum)
+ }
+ }
+ }
+ local width = boundingbox[3]
+ local height = boundingbox[4]
+ local xform = img.scan {
+ attr = resources(),
+ stream = format("%s 0 0 %s 0 0 cm /%s Do",width,height,imagetag),
+ bbox = { 0, 0, width/factor, height/factor },
+ }
+ img.immediatewrite(xform)
+ return xform
+end
-codeinjections.finalizepage = lpdf.finalizepage
-codeinjections.finalizedocument = lpdf.finalizedocument
+-- till here
backends.install("pdf")